@betterstart/cli 0.1.72 → 0.1.74

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.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/generate.ts","../src/config/resolver.ts","../src/core/schema-reader.ts","../src/core/field-helpers/walking.ts","../src/core/field-helpers/flattening.ts","../src/core/field-helpers/form-fields.ts","../src/generators/email-template.ts","../src/utils/string.ts","../src/generators/form-admin/orchestrator.ts","../src/generators/form-admin/admin-columns.ts","../src/generators/form-admin/admin-page.ts","../src/generators/form-admin/admin-page-content.ts","../src/generators/form-admin/admin-settings-page.ts","../src/generators/form-admin/admin-table.ts","../src/generators/form-admin/admin-view-page.ts","../src/generators/form-navigation.ts","../src/generators/form-pipeline/form-actions.ts","../src/generators/form-pipeline/form-component-multistep.ts","../src/generators/form-pipeline/form-component-shared.ts","../src/core/type-mappers/drizzle.ts","../src/core/type-mappers/zod.ts","../src/core/type-mappers/typescript.ts","../src/generators/form-pipeline/form-component-single.ts","../src/generators/form-pipeline/form-component.ts","../src/generators/form-pipeline/form-database.ts","../src/generators/form-pipeline/form-hook.ts","../src/generators/form-pipeline/pipeline.ts","../src/generators/actions/entity-actions.ts","../src/core/constants.ts","../src/generators/actions/action-helpers.ts","../src/generators/actions/entity-file-contents.ts","../src/generators/actions/single-actions.ts","../src/generators/cache.ts","../src/generators/columns/generate-columns.ts","../src/generators/columns/column-defs.ts","../src/generators/columns/column-actions.ts","../src/generators/columns/custom-cell.ts","../src/generators/create-page.ts","../src/generators/database.ts","../src/generators/edit-page.ts","../src/generators/form/form-entity.ts","../src/generators/form/zod-schema.ts","../src/generators/form/field-jsx-nested.ts","../src/generators/form/field-jsx.ts","../src/generators/form/form-shared.ts","../src/generators/form/form-single.ts","../src/generators/hook.ts","../src/generators/navigation.ts","../src/generators/page.ts","../src/generators/page-content.ts","../src/generators/single-page.ts","../src/generators/table.ts","../src/generators/index.ts","../src/generators/post-generate.ts","../src/utils/package-manager.ts","../src/commands/init.ts","../src/init/prompts/database.ts","../src/init/prompts/features.ts","../src/init/prompts/project.ts","../src/init/scaffolders/api-routes.ts","../src/utils/fs.ts","../src/init/scaffolders/auth.ts","../src/init/scaffolders/base.ts","../src/init/scaffolders/biome.ts","../src/init/scaffolders/components.ts","../src/utils/detect.ts","../src/init/templates/data/cms.ts","../src/init/scaffolders/database.ts","../src/init/scaffolders/dependencies.ts","../src/init/scaffolders/env.ts","../src/utils/env.ts","../src/init/scaffolders/layout.ts","../src/init/scaffolders/preset.ts","../src/init/templates/presets/blog-categories.ts","../src/init/templates/presets/blog-posts.ts","../src/init/templates/presets/default-settings.ts","../src/init/templates/presets/full-contact.ts","../src/init/templates/presets/full-navigation.ts","../src/init/scaffolders/tailwind.ts","../src/init/scaffolders/tsconfig.ts","../src/commands/seed.ts","../src/commands/remove.ts","../src/commands/setup-r2.ts","../src/commands/uninstall.ts","../src/commands/uninstall-cleaners.ts","../src/commands/update-component.ts","../src/commands/update-deps.ts","../src/commands/update-styles.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { generateCommand } from './commands/generate.js'\nimport { initCommand } from './commands/init.js'\nimport { removeCommand } from './commands/remove.js'\nimport { seedCommand } from './commands/seed.js'\nimport { setupR2Command } from './commands/setup-r2.js'\nimport { uninstallCommand } from './commands/uninstall.js'\nimport { updateComponentCommand } from './commands/update-component.js'\nimport { updateDepsCommand } from './commands/update-deps.js'\nimport { updateStylesCommand } from './commands/update-styles.js'\n\nconst program = new Command()\n\nprogram\n .name('betterstart')\n .description('Scaffold a full-featured CMS into any Next.js 16 application')\n .version('0.1.0')\n\nprogram.addCommand(initCommand)\nprogram.addCommand(generateCommand)\nprogram.addCommand(removeCommand)\nprogram.addCommand(seedCommand)\nprogram.addCommand(setupR2Command)\nprogram.addCommand(uninstallCommand)\nprogram.addCommand(updateComponentCommand)\nprogram.addCommand(updateDepsCommand)\nprogram.addCommand(updateStylesCommand)\n\nprogram.parse()\n","/**\n * generate command — read schema, detect type, run pipeline\n */\n\nimport path from 'node:path'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport type { LoadedSchema } from '../core/schema-reader.js'\nimport { listEntitySchemas, listFormSchemas, loadSchema, SchemaNotFoundError, validateLoadedSchema } from '../core/schema-reader.js'\nimport { runFormPipeline } from '../generators/form-pipeline/index.js'\nimport { runEntityPipeline, runSinglePipeline } from '../generators/index.js'\nimport { runPostGenerate } from '../generators/post-generate.js'\n\nexport const generateCommand = new Command('generate')\n .alias('g')\n .description('Generate entity or form from a JSON schema')\n .argument('[schema]', 'Schema name (e.g. posts, categories, contact)')\n .option('-f, --force', 'Overwrite existing generated files', false)\n .option('-a, --all', 'Regenerate all schemas', false)\n .option('--skip-migration', 'Skip running db:push after generation', false)\n .option('--cwd <path>', 'Project root path')\n .action(\n async (\n schemaName: string | undefined,\n options: { force: boolean; all: boolean; skipMigration: boolean; cwd?: string }\n ) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n if (options.all) {\n await generateAll(cwd, options)\n return\n }\n\n if (!schemaName) {\n console.error(' Error: schema name is required (or use --all)')\n process.exit(1)\n }\n\n console.log('\\n BetterStart Generator\\n')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n console.log(` Project root: ${cwd}`)\n console.log(` Loading schema: ${schemaName}.json\\n`)\n\n // Load schema\n let loaded: LoadedSchema\n try {\n loaded = loadSchema(schemasDir, schemaName)\n } catch (err) {\n if (err instanceof SchemaNotFoundError) {\n console.error(` ${err.message}`)\n console.error(\n `\\n Create a schema file at: ${path.join(schemasDir, `${schemaName}.json`)}`\n )\n } else {\n console.error(\n ` Error loading schema: ${err instanceof Error ? err.message : String(err)}`\n )\n }\n process.exit(1)\n }\n\n // Validate schema\n const validationErrors = validateLoadedSchema(loaded)\n if (validationErrors.length > 0) {\n console.error(' Schema validation failed:\\n')\n for (const error of validationErrors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n console.log(` Schema validated (type: ${loaded.type})\\n`)\n\n // Route to correct pipeline\n if (loaded.type === 'form') {\n console.log(' Generating form files...\\n')\n\n const result = runFormPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Form generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n console.log('\\n Form generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n return\n }\n\n // Single pipeline\n if (loaded.type === 'single') {\n console.log(' Generating single schema files...\\n')\n\n const result = runSinglePipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Single generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n console.log('\\n Single generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n return\n }\n\n // Entity pipeline\n console.log(' Generating files...\\n')\n\n const result = runEntityPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n // Summary\n console.log('\\n Generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n // Post-generation: db:push + lint:fix\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n }\n )\n\n// ============================================================================\n// --all: regenerate every schema\n// ============================================================================\n\nasync function generateAll(\n cwd: string,\n options: { force: boolean; skipMigration: boolean }\n) {\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n const entityNames = listEntitySchemas(schemasDir)\n const formNames = listFormSchemas(schemasDir)\n const allNames = [...entityNames, ...formNames]\n\n if (allNames.length === 0) {\n console.error(`\\n No schemas found in ${schemasDir}\\n`)\n process.exit(1)\n }\n\n console.log(`\\n BetterStart Generator — regenerating ${allNames.length} schema(s)\\n`)\n\n let totalFiles = 0\n const failed: string[] = []\n\n for (const name of allNames) {\n try {\n const loaded = loadSchema(schemasDir, name)\n const validationErrors = validateLoadedSchema(loaded)\n if (validationErrors.length > 0) {\n console.error(` ✗ ${name} — validation failed`)\n failed.push(name)\n continue\n }\n\n let files: string[] = []\n\n if (loaded.type === 'form') {\n const result = runFormPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n } else if (loaded.type === 'single') {\n const result = runSinglePipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n } else {\n const result = runEntityPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n }\n\n totalFiles += files.length\n console.log(` ✓ ${name} (${loaded.type}) — ${files.length} files`)\n } catch (err) {\n console.error(` ✗ ${name} — ${err instanceof Error ? err.message : String(err)}`)\n failed.push(name)\n }\n }\n\n // Run post-generate once at the end\n if (!options.skipMigration) {\n runPostGenerate(cwd, allNames[0], { skipMigration: false })\n }\n\n console.log(`\\n Done! ${totalFiles} files generated across ${allNames.length} schema(s).`)\n if (failed.length > 0) {\n console.error(` ${failed.length} failed: ${failed.join(', ')}`)\n }\n console.log('')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { BetterstartConfig } from './types.js'\n\nconst CONFIG_FILE_NAME = 'cms.config.ts'\n\nexport function getDefaultConfig(srcDir: boolean): BetterstartConfig {\n const appBase = srcDir ? './src/app' : './app'\n return {\n srcDir,\n paths: {\n cms: './cms',\n schemas: './cms/schemas',\n pages: `${appBase}/(cms)/cms/(authenticated)`,\n login: `${appBase}/(cms)/cms/login`,\n api: `${appBase}/(cms)/api/cms`\n },\n database: {\n provider: 'neon',\n migrationsDir: './cms/db/migrations'\n },\n features: {\n email: true\n },\n linter: 'biome',\n generated: {\n entities: [],\n singles: [],\n forms: []\n }\n }\n}\n\nexport function findConfigFile(cwd: string): string | undefined {\n const filePath = path.join(cwd, CONFIG_FILE_NAME)\n if (fs.existsSync(filePath)) {\n return filePath\n }\n return undefined\n}\n\nexport async function loadConfigFile(configPath: string): Promise<BetterstartConfig> {\n const { createJiti } = await import('jiti')\n\n const alias: Record<string, string> = {}\n try {\n alias['@betterstart/cli'] = fileURLToPath(import.meta.resolve('@betterstart/cli'))\n } catch {\n // Not critical — config may not import from us\n }\n\n const jiti = createJiti(import.meta.url, { alias })\n const mod = await jiti.import(configPath)\n return ((mod as Record<string, unknown>).default || mod) as BetterstartConfig\n}\n\nexport async function resolveConfig(cwd?: string): Promise<BetterstartConfig> {\n const workingDir = cwd ?? process.cwd()\n const configPath = findConfigFile(workingDir)\n\n if (!configPath) {\n const hasSrc = fs.existsSync(path.join(workingDir, 'src'))\n return getDefaultConfig(hasSrc)\n }\n\n return loadConfigFile(configPath)\n}\n","/**\n * Schema reader: load + validate JSON schemas from cms/schemas/\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, Schema } from '../types.js'\nimport { flattenFields } from './field-helpers/index.js'\n\n// ============================================================================\n// Schema Types\n// ============================================================================\n\nexport type SchemaType = 'entity' | 'single' | 'form'\n\nexport interface LoadedEntitySchema {\n type: 'entity'\n schema: Schema\n filePath: string\n}\n\nexport interface LoadedSingleSchema {\n type: 'single'\n schema: Schema\n filePath: string\n}\n\nexport interface LoadedFormSchema {\n type: 'form'\n schema: FormSchema\n filePath: string\n}\n\nexport type LoadedSchema = LoadedEntitySchema | LoadedSingleSchema | LoadedFormSchema\n\n// ============================================================================\n// Schema Loading\n// ============================================================================\n\n/**\n * Load a schema by name from the schemas directory\n * Detects entity vs form schemas automatically\n */\nexport function loadSchema(schemasDir: string, name: string): LoadedSchema {\n // Check for form schema first (in forms/ subdirectory)\n const formPath = path.join(schemasDir, 'forms', `${name}.json`)\n if (fs.existsSync(formPath)) {\n const content = fs.readFileSync(formPath, 'utf-8')\n const parsed = parseJson(content, formPath)\n return { type: 'form', schema: parsed as FormSchema, filePath: formPath }\n }\n\n // Check for entity schema\n const entityPath = path.join(schemasDir, `${name}.json`)\n if (!fs.existsSync(entityPath)) {\n throw new SchemaNotFoundError(name, schemasDir)\n }\n\n const content = fs.readFileSync(entityPath, 'utf-8')\n const parsed = parseJson(content, entityPath)\n\n const obj = parsed as Record<string, unknown>\n\n // Auto-detect form type from schema content\n if ('submitButtonText' in obj || 'steps' in obj) {\n return { type: 'form', schema: parsed as FormSchema, filePath: entityPath }\n }\n\n // Detect single schema via explicit type field\n if (obj.type === 'single') {\n return { type: 'single', schema: parsed as Schema, filePath: entityPath }\n }\n\n return { type: 'entity', schema: parsed as Schema, filePath: entityPath }\n}\n\n/**\n * List all available entity schemas in the schemas directory\n */\nexport function listEntitySchemas(schemasDir: string): string[] {\n if (!fs.existsSync(schemasDir)) return []\n return fs\n .readdirSync(schemasDir)\n .filter((f) => f.endsWith('.json') && f !== 'schema.json')\n .map((f) => f.replace('.json', ''))\n}\n\n/**\n * List all available form schemas\n */\nexport function listFormSchemas(schemasDir: string): string[] {\n const formsDir = path.join(schemasDir, 'forms')\n if (!fs.existsSync(formsDir)) return []\n return fs\n .readdirSync(formsDir)\n .filter((f) => f.endsWith('.json'))\n .map((f) => f.replace('.json', ''))\n}\n\n// ============================================================================\n// Schema Validation\n// ============================================================================\n\n/**\n * Validate an entity schema structure\n * Returns an array of error messages (empty = valid)\n */\nexport function validateEntitySchema(schema: Schema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\n if (!Array.isArray(schema.columns) || schema.columns.length === 0) {\n errors.push('Schema must have at least one column')\n }\n\n // Validate fields\n for (const field of schema.fields || []) {\n if (field.type === 'separator') continue\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // Validate columns reference real fields\n const flatFields = flattenFields(schema.fields || [])\n const fieldNames = new Set(flatFields.map((f) => f.name))\n // Auto fields are always available\n for (const auto of [\n 'id',\n 'createdAt',\n 'updatedAt',\n 'published',\n 'submittedAt',\n 'ipAddress',\n 'userAgent'\n ]) {\n fieldNames.add(auto)\n }\n\n for (const column of schema.columns || []) {\n if (!column.accessorKey || !column.header || !column.type) {\n errors.push(`Column is missing required properties: ${JSON.stringify(column)}`)\n } else if (!fieldNames.has(column.accessorKey)) {\n errors.push(\n `Column accessorKey \"${column.accessorKey}\" does not match any field. Available: ${Array.from(fieldNames).join(', ')}`\n )\n }\n }\n\n return errors\n}\n\n/**\n * Validate a single schema structure\n * Like entity validation but skips columns requirement (no list view)\n */\nexport function validateSingleSchema(schema: Schema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\n\n // Validate fields\n for (const field of schema.fields || []) {\n if (field.type === 'separator') continue\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // No columns validation — single schemas have no list view\n\n return errors\n}\n\n/**\n * Validate a form schema structure\n */\nexport function validateFormSchema(schema: FormSchema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Form schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Form schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Form schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Form schema must have a valid \"icon\" field')\n }\n\n const hasFields = Array.isArray(schema.fields) && schema.fields.length > 0\n const hasSteps = Array.isArray(schema.steps) && schema.steps.length > 0\n\n if (!hasFields && !hasSteps) {\n errors.push('Form schema must have either \"fields\" or \"steps\"')\n }\n if (hasFields && hasSteps) {\n errors.push('Form schema cannot have both \"fields\" and \"steps\"')\n }\n\n if (hasSteps) {\n for (const step of schema.steps!) {\n if (!step.name || !step.label) {\n errors.push(`Form step is missing name or label: ${JSON.stringify(step)}`)\n }\n if (!Array.isArray(step.fields) || step.fields.length === 0) {\n errors.push(`Form step \"${step.name}\" must have at least one field`)\n }\n }\n }\n\n return errors\n}\n\n/**\n * Validate a loaded schema (auto-detects type)\n */\nexport function validateLoadedSchema(loaded: LoadedSchema): string[] {\n if (loaded.type === 'entity') {\n return validateEntitySchema(loaded.schema)\n }\n if (loaded.type === 'single') {\n return validateSingleSchema(loaded.schema)\n }\n return validateFormSchema(loaded.schema)\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nexport class SchemaNotFoundError extends Error {\n constructor(name: string, schemasDir: string) {\n super(\n `Schema \"${name}\" not found. Looked in:\\n - ${path.join(schemasDir, `${name}.json`)}\\n - ${path.join(schemasDir, 'forms', `${name}.json`)}`\n )\n this.name = 'SchemaNotFoundError'\n }\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nfunction parseJson(content: string, filePath: string): unknown {\n try {\n return JSON.parse(content)\n } catch {\n throw new Error(`Failed to parse JSON schema: ${filePath}`)\n }\n}\n","/**\n * Field tree walking and type checking utilities\n */\n\nimport type { SchemaField } from '../../types.js'\n\n// ============================================================================\n// Field Tree Walking\n// ============================================================================\n\nexport interface WalkFieldsOptions {\n includeLists?: boolean\n includeGroups?: boolean\n includeTabs?: boolean\n}\n\nconst DEFAULT_WALK_OPTIONS: WalkFieldsOptions = {\n includeLists: true,\n includeGroups: true,\n includeTabs: true\n}\n\n/**\n * Walk through all fields in a schema, including nested ones\n */\nexport function walkFields(\n fields: SchemaField[],\n callback: (field: SchemaField, depth: number, parent?: SchemaField) => void,\n options: WalkFieldsOptions = DEFAULT_WALK_OPTIONS\n): void {\n function walk(fieldsToWalk: SchemaField[], depth: number, parent?: SchemaField): void {\n for (const field of fieldsToWalk) {\n callback(field, depth, parent)\n\n if (options.includeGroups && (field.type === 'group' || field.type === 'section') && field.fields) {\n walk(field.fields, depth + 1, field)\n }\n if (options.includeLists && field.type === 'list' && field.fields) {\n walk(field.fields, depth + 1, field)\n }\n if (options.includeTabs && field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n walk(tab.fields, depth + 1, field)\n }\n }\n }\n }\n }\n\n walk(fields, 0)\n}\n\n// ============================================================================\n// Field Type Checking\n// ============================================================================\n\n/**\n * Check if any field in the tree matches a specific type\n */\nexport function hasFieldType(\n fields: SchemaField[],\n type: string,\n options?: WalkFieldsOptions\n): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (field.type === type) found = true\n },\n options\n )\n return found\n}\n\n/**\n * Check if any field in the tree matches any of the given types\n */\nexport function hasAnyFieldType(\n fields: SchemaField[],\n types: string[],\n options?: WalkFieldsOptions\n): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (types.includes(field.type)) found = true\n },\n options\n )\n return found\n}\n\n/**\n * Check if any field uses icons (either icon type or hasIcon property)\n */\nexport function hasIconUsage(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (field.type === 'icon' || field.hasIcon) found = true\n },\n options\n )\n return found\n}\n\nexport function hasRelationshipField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'relationship', options)\n}\n\nexport function hasMarkdownField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'markdown', options)\n}\n\nexport function hasTextareaField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'text', options)\n}\n\n/**\n * Collect all fields of a specific type\n */\nexport function collectFieldsByType(\n fields: SchemaField[],\n type: string,\n options?: WalkFieldsOptions\n): SchemaField[] {\n const result: SchemaField[] = []\n walkFields(\n fields,\n (field) => {\n if (field.type === type) result.push(field)\n },\n options\n )\n return result\n}\n","/**\n * Field flattening and collection utilities\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { collectFieldsByType } from './walking.js'\n\n// ============================================================================\n// Field Flattening\n// ============================================================================\n\nconst AUTO_ID_FIELD: SchemaField = {\n name: 'id',\n type: 'serial',\n primaryKey: true\n}\n\n/**\n * Ensure fields have an ID field - automatically injects one if not present\n */\nexport function ensureIdField(fields: SchemaField[]): SchemaField[] {\n const hasId = fields.some((f) => f.primaryKey || f.name === 'id')\n return hasId ? fields : [AUTO_ID_FIELD, ...fields]\n}\n\n/**\n * Flatten group and tabs fields into individual fields for database operations\n * Automatically ensures an ID field exists\n */\nexport function flattenFields(fields: SchemaField[]): SchemaField[] {\n return flattenFieldsWithoutIdCheck(ensureIdField(fields))\n}\n\nfunction flattenFieldsWithoutIdCheck(fields: SchemaField[]): SchemaField[] {\n const flattened: SchemaField[] = []\n\n for (const field of fields) {\n if ((field.type === 'group' || field.type === 'section') && field.fields) {\n flattened.push(...flattenFieldsWithoutIdCheck(field.fields))\n } else if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n flattened.push(...flattenFieldsWithoutIdCheck(tab.fields))\n }\n }\n } else {\n flattened.push(field)\n }\n }\n\n return flattened\n}\n\n// ============================================================================\n// Field Collection\n// ============================================================================\n\n/**\n * Get all many-to-many relationship fields\n */\nexport function getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n const flat = flattenFields(fields)\n return flat.filter((f) => f.type === 'relationship' && f.multiple === true && f.relationship)\n}\n\n/**\n * Get all single relationship fields (excluding many-to-many)\n */\nexport function getNestedRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship && !f.multiple) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) collect(f.fields)\n if (f.type === 'list' && f.fields) collect(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collect(tab.fields)\n }\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Collect relationship fields from top-level and groups only (not lists)\n */\nexport function collectRelationshipFieldsTopLevel(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n collect(f.fields)\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Collect ALL relationship fields including those in lists\n */\nexport function collectAllRelationshipFields(fields: SchemaField[]): SchemaField[] {\n return collectFieldsByType(fields, 'relationship')\n}\n\n/**\n * Get list fields that have nested fields (not just items)\n */\nexport function getListFieldsWithNestedFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n collect(f.fields)\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Get nested list fields (list fields inside list fields)\n */\nexport function getNestedListFields(\n fields: SchemaField[]\n): { parent: SchemaField; nested: SchemaField }[] {\n const result: { parent: SchemaField; nested: SchemaField }[] = []\n\n const listFields = getListFieldsWithNestedFields(fields)\n for (const parent of listFields) {\n if (parent.fields) {\n for (const nested of parent.fields) {\n if (nested.type === 'list' && nested.fields && nested.fields.length > 0) {\n result.push({ parent, nested })\n }\n }\n }\n }\n\n return result\n}\n","/**\n * Form schema field helpers (for FormSchema type)\n */\n\nimport type { FormField, FormSchema, FormStep } from '../../types.js'\n\n/**\n * Get all fields from a form schema (including from steps), flattening groups\n */\nexport function getAllFormFields(schema: FormSchema): FormField[] {\n const allFields: FormField[] = []\n\n const sources = schema.steps ? schema.steps.flatMap((step) => step.fields) : schema.fields || []\n\n for (const field of sources) {\n if (field.type === 'group' && field.fields) {\n for (const nestedField of field.fields) {\n allFields.push({\n ...nestedField,\n condition: nestedField.condition || field.condition\n })\n }\n } else {\n allFields.push(field)\n }\n }\n\n return allFields\n}\n\n/**\n * Check if a form schema is multi-step\n */\nexport function isMultiStepForm(schema: FormSchema): boolean {\n return Array.isArray(schema.steps) && schema.steps.length > 0\n}\n\n/**\n * Get all concrete fields from a form schema, flattening groups and skipping dynamicFields.\n * Works with both flat schemas (schema.fields) and multi-step schemas (schema.steps).\n */\nexport function getAllFormSchemaFields(schema: FormSchema): FormField[] {\n const flatten = (fields: FormField[]): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'dynamicFields') return []\n if (field.type === 'group' && field.fields) return flatten(field.fields)\n return field.type === 'group' ? [] : [field]\n })\n }\n if (schema.fields) return flatten(schema.fields)\n if (schema.steps) return schema.steps.flatMap((step) => flatten(step.fields))\n return []\n}\n\n/**\n * Get flat array of field names for a form step (for RHF trigger validation).\n * Groups are flattened to child names, list fields use parent name,\n * hidden and dynamicFields are excluded, showWhen fields are included.\n */\nexport function getStepFieldNames(step: FormStep): string[] {\n const names: string[] = []\n const collect = (fields: FormField[]): void => {\n for (const field of fields) {\n if (field.hidden) continue\n if (field.type === 'dynamicFields') continue\n if (field.type === 'group' && field.fields) {\n collect(field.fields)\n } else if (field.name) {\n names.push(field.name)\n }\n }\n }\n collect(step.fields)\n return names\n}\n\n/**\n * Check if a form schema contains dynamicFields\n */\nexport function hasDynamicFields(schema: FormSchema): boolean {\n const check = (fields: FormField[]): boolean => {\n for (const f of fields) {\n if (f.type === 'dynamicFields') return true\n if (f.type === 'group' && f.fields && check(f.fields)) return true\n }\n return false\n }\n if (schema.fields && check(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (check(step.fields)) return true\n }\n }\n return false\n}\n","/**\n * Email template generator: creates React Email template for form submission notifications\n * Output: cms/lib/emails/<name>-submission.tsx\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { getAllFormSchemaFields, hasDynamicFields } from '../core/field-helpers/index.js'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types.js'\nimport { toPascalCase, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Type Mapping\n// ============================================================================\n\nfunction getTypeForField(field: FormField): string {\n switch (field.type) {\n case 'number':\n return 'number | null'\n case 'checkbox':\n return 'boolean | null'\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) return 'Record<string, unknown>[] | null'\n return 'string[] | null'\n default:\n return 'string | null'\n }\n}\n\n// ============================================================================\n// Field Value Rendering\n// ============================================================================\n\nfunction generateFieldValue(field: FormField): string {\n const name = field.name || ''\n\n switch (field.type) {\n case 'checkbox':\n return `{${name} ? 'Yes' : 'No'}`\n case 'upload':\n case 'file':\n return `{${name} ? (\n <Link href={${name}} style={link}>Download File</Link>\n ) : 'No file uploaded'}`\n case 'email':\n return `{${name} ? (\n <Link href={\\`mailto:\\${${name}}\\`} style={link}>{${name}}</Link>\n ) : 'N/A'}`\n case 'url':\n return `{${name} ? (\n <Link href={${name}} style={link}>{${name}}</Link>\n ) : 'N/A'}`\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) {\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? (\n ${name}.map((item, idx) => (\n <Text key={idx} style={listItem}>\n {Object.entries(item).map(([k, v]) => \\`\\${k}: \\${v}\\`).join(', ')}\n </Text>\n ))\n ) : 'N/A'}`\n }\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? ${name}.join(', ') : 'N/A'}`\n case 'date':\n return `{${name} ? new Date(${name}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : 'N/A'}`\n default:\n return `{${name} ?? 'N/A'}`\n }\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface EmailTemplateResult {\n files: string[]\n}\n\nexport function generateEmailTemplate(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): EmailTemplateResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const fields = getAllFormSchemaFields(schema).filter((f) => f.name)\n const includeDynamic = hasDynamicFields(schema)\n\n const kebab = toKebabCase(formName)\n const filePath = path.join(cwd, cmsDir, 'lib', 'emails', `${kebab}-submission.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const needsLink = fields.some(\n (f) => f.type === 'upload' || f.type === 'file' || f.type === 'email' || f.type === 'url'\n )\n const needsListItem = fields.some(\n (f) => (f.type === 'list' || f.type === 'multiselect') && f.fields && f.fields.length > 0\n )\n\n // Props interface\n const propsFields = fields.map((f) => ` ${f.name}: ${getTypeForField(f)}`).join('\\n')\n const customFieldsProp = includeDynamic ? '\\n customFields?: Record<string, unknown> | null' : ''\n\n // Field sections in email body\n const fieldSections = fields\n .map(\n (f) => ` <Row style={fieldRow}>\n <Text style={label}>${f.label}</Text>\n <Text style={value}>${generateFieldValue(f)}</Text>\n </Row>`\n )\n .join('\\n\\n')\n\n // Dynamic fields section\n const customFieldsSection = includeDynamic\n ? `\n\n {customFields && Object.keys(customFields).length > 0 && (\n <>\n <Row style={dividerRow}>\n <Text style={sectionTitle}>Additional Information</Text>\n </Row>\n {Object.entries(customFields).map(([fieldKey, fieldValue]) => (\n <Row key={fieldKey} style={fieldRow}>\n <Text style={label}>{fieldKey.replace(/([A-Z])/g, ' $1').trim()}</Text>\n <Text style={value}>{fieldValue !== null && fieldValue !== undefined ? String(fieldValue) : 'N/A'}</Text>\n </Row>\n ))}\n </>\n )}`\n : ''\n\n // Props destructuring\n const propsDestructured = [\n ...fields.map((f) => f.name),\n ...(includeDynamic ? ['customFields'] : []),\n 'submittedAt'\n ].join(',\\n ')\n\n // Optional style blocks\n const linkStyle = needsLink\n ? `\nconst link = {\n color: colors.primary,\n fontWeight: '500' as const,\n textDecoration: 'none',\n}\n`\n : ''\n\n const listItemStyle = needsListItem\n ? `\nconst listItem = {\n backgroundColor: colors.borderLight,\n borderRadius: '6px',\n color: colors.text,\n fontSize: '14px',\n lineHeight: '20px',\n marginBottom: '6px',\n padding: '8px 12px',\n}\n`\n : ''\n\n const dynamicStyles = includeDynamic\n ? `\nconst dividerRow = {\n borderTop: \\`2px solid \\${colors.border}\\`,\n marginTop: '8px',\n paddingTop: '24px',\n}\n\nconst sectionTitle = {\n color: colors.text,\n fontSize: '14px',\n fontWeight: '600' as const,\n margin: '0 0 8px',\n}\n`\n : ''\n\n const content = `import { Body, Container, Head, Heading, Html${needsLink ? ', Link' : ''}, Preview, Row, Section, Text } from '@react-email/components'\n\ninterface ${pascal}SubmissionEmailProps {\n${propsFields}${customFieldsProp}\n submittedAt: string\n}\n\nexport function ${pascal}SubmissionEmail({\n ${propsDestructured}\n}: ${pascal}SubmissionEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>New ${schema.label} Submission</Preview>\n <Body style={main}>\n <Container style={container}>\n <Section style={header}>\n <Text style={logoText}>BetterStart</Text>\n </Section>\n\n <Section style={titleSection}>\n <Heading style={h1}>New ${schema.label} Submission</Heading>\n <Text style={subtitle}>\n You received a new submission on {new Date(submittedAt).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}\n </Text>\n </Section>\n\n <Section style={card}>\n${fieldSections}${customFieldsSection}\n </Section>\n\n <Section style={footer}>\n <Text style={footerText}>\n Submitted at {new Date(submittedAt).toLocaleString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true, timeZoneName: 'short' })}\n </Text>\n <Text style={footerBrand}>BetterStart</Text>\n </Section>\n </Container>\n </Body>\n </Html>\n )\n}\n\nconst colors = {\n primary: '#7c3aed',\n background: '#f8fafc',\n cardBg: '#ffffff',\n text: '#1e293b',\n textMuted: '#64748b',\n textLight: '#94a3b8',\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n}\n\nconst main = {\n backgroundColor: colors.background,\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n padding: '40px 20px',\n}\n\nconst container = {\n margin: '0 auto',\n maxWidth: '600px',\n}\n\nconst header = {\n backgroundColor: colors.primary,\n borderRadius: '12px 12px 0 0',\n padding: '24px 32px',\n textAlign: 'center' as const,\n}\n\nconst logoText = {\n color: '#ffffff',\n fontSize: '24px',\n fontWeight: '700' as const,\n letterSpacing: '-0.02em',\n margin: '0',\n}\n\nconst titleSection = {\n backgroundColor: colors.cardBg,\n padding: '32px 32px 24px',\n textAlign: 'center' as const,\n}\n\nconst h1 = {\n color: colors.text,\n fontSize: '24px',\n fontWeight: '700' as const,\n lineHeight: '32px',\n margin: '0 0 8px',\n}\n\nconst subtitle = {\n color: colors.textMuted,\n fontSize: '14px',\n lineHeight: '20px',\n margin: '0',\n}\n\nconst card = {\n backgroundColor: colors.cardBg,\n padding: '0 32px 32px',\n}\n\nconst fieldRow = {\n borderBottom: \\`1px solid \\${colors.borderLight}\\`,\n padding: '16px 0',\n}\n\nconst label = {\n color: colors.textMuted,\n fontSize: '12px',\n fontWeight: '600' as const,\n letterSpacing: '0.025em',\n lineHeight: '16px',\n margin: '0 0 6px',\n textTransform: 'uppercase' as const,\n}\n\nconst value = {\n color: colors.text,\n fontSize: '16px',\n lineHeight: '24px',\n margin: '0',\n wordBreak: 'break-word' as const,\n}\n${linkStyle}${listItemStyle}${dynamicStyles}const footer = {\n backgroundColor: colors.cardBg,\n borderRadius: '0 0 12px 12px',\n borderTop: \\`1px solid \\${colors.border}\\`,\n padding: '24px 32px',\n textAlign: 'center' as const,\n}\n\nconst footerText = {\n color: colors.textLight,\n fontSize: '12px',\n lineHeight: '16px',\n margin: '0 0 8px',\n}\n\nconst footerBrand = {\n color: colors.textMuted,\n fontSize: '14px',\n fontWeight: '600' as const,\n margin: '0',\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Shared string helpers used across all generators.\n */\n\nexport function toPascalCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .split(/[-_\\s]+/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join('')\n}\n\nexport function toCamelCase(str: string): string {\n const p = toPascalCase(str)\n return p.charAt(0).toLowerCase() + p.slice(1)\n}\n\nexport function singularize(str: string): string {\n if (str.endsWith('ies')) return `${str.slice(0, -3)}y`\n if (str.endsWith('ves')) return `${str.slice(0, -3)}f`\n if (\n str.endsWith('sses') ||\n str.endsWith('xes') ||\n str.endsWith('ches') ||\n str.endsWith('shes') ||\n str.endsWith('zes')\n )\n return str.slice(0, -2)\n if (str.endsWith('s') && !str.endsWith('ss')) return str.slice(0, -1)\n return str\n}\n\nexport function pluralize(str: string): string {\n if (str.endsWith('s') && !str.endsWith('ss')) return str\n if (str.endsWith('y') && !['ay', 'ey', 'iy', 'oy', 'uy'].some((v) => str.endsWith(v)))\n return `${str.slice(0, -1)}ies`\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('ch') || str.endsWith('sh'))\n return `${str}es`\n return `${str}s`\n}\n\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase()\n}\n\nexport function toScreamingSnake(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toUpperCase()\n}\n\nexport function quotePropertyName(name: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `'${name}'`\n}\n\nexport function singularizeLabel(label: string): string {\n const words = label.split(' ')\n const lastWord = words[words.length - 1]\n words[words.length - 1] = singularize(lastWord.toLowerCase())\n words[words.length - 1] =\n words[words.length - 1].charAt(0).toUpperCase() + words[words.length - 1].slice(1)\n return words.join(' ')\n}\n","/**\n * Form admin pages generator: creates admin UI for viewing/managing form submissions\n *\n * Generates under (authenticated)/forms/<name>/:\n * page.tsx, columns.tsx, <name>-submissions-table.tsx,\n * <name>-submissions-page-content.tsx, [id]/view/page.tsx\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { getAllFormSchemaFields, hasDynamicFields } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\nimport { generateColumns } from './admin-columns.js'\nimport { generatePage } from './admin-page.js'\nimport { generatePageContent } from './admin-page-content.js'\nimport { generateSettingsPage } from './admin-settings-page.js'\nimport { generateTable } from './admin-table.js'\nimport { generateViewPage } from './admin-view-page.js'\n\n// ============================================================================\n// Result Type\n// ============================================================================\n\nexport interface FormAdminPagesResult {\n files: string[]\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\nexport function generateFormAdminPages(\n schema: FormSchema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions\n): FormAdminPagesResult {\n const formName = schema.name\n const kebab = toKebabCase(formName)\n const pascal = toPascalCase(formName)\n const camel = toCamelCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const adminDir = path.join(cwd, pagesDir, 'forms', kebab)\n if (!fs.existsSync(adminDir)) fs.mkdirSync(adminDir, { recursive: true })\n\n const files: string[] = []\n const rel = (p: string) => path.relative(cwd, p)\n\n // 1. page.tsx\n const pagePath = path.join(adminDir, 'page.tsx')\n if (!fs.existsSync(pagePath) || options.force) {\n fs.writeFileSync(pagePath, generatePage(pascal, kebab), 'utf-8')\n }\n files.push(rel(pagePath))\n\n // 2. columns.tsx\n const columnsPath = path.join(adminDir, 'columns.tsx')\n if (!fs.existsSync(columnsPath) || options.force) {\n fs.writeFileSync(\n columnsPath,\n generateColumns(fields, pascal, kebab, camel, schema.columns),\n 'utf-8'\n )\n }\n files.push(rel(columnsPath))\n\n // 3. submissions-table.tsx\n const tablePath = path.join(adminDir, `${kebab}-submissions-table.tsx`)\n if (!fs.existsSync(tablePath) || options.force) {\n fs.writeFileSync(tablePath, generateTable(pascal, kebab, schema.label), 'utf-8')\n }\n files.push(rel(tablePath))\n\n // 4. submissions-page-content.tsx\n const contentPath = path.join(adminDir, `${kebab}-submissions-page-content.tsx`)\n if (!fs.existsSync(contentPath) || options.force) {\n fs.writeFileSync(contentPath, generatePageContent(pascal, kebab, camel, schema.label), 'utf-8')\n }\n files.push(rel(contentPath))\n\n // 5. [id]/view/page.tsx\n const viewDir = path.join(adminDir, '[id]', 'view')\n if (!fs.existsSync(viewDir)) fs.mkdirSync(viewDir, { recursive: true })\n const viewPath = path.join(viewDir, 'page.tsx')\n if (!fs.existsSync(viewPath) || options.force) {\n fs.writeFileSync(\n viewPath,\n generateViewPage(pascal, kebab, fields, schema.label, hasDynamicFields(schema)),\n 'utf-8'\n )\n }\n files.push(rel(viewPath))\n\n // 6. settings/page.tsx\n const settingsDir = path.join(adminDir, 'settings')\n if (!fs.existsSync(settingsDir)) fs.mkdirSync(settingsDir, { recursive: true })\n const settingsPath = path.join(settingsDir, 'page.tsx')\n if (!fs.existsSync(settingsPath) || options.force) {\n fs.writeFileSync(settingsPath, generateSettingsPage(pascal, kebab, schema.label), 'utf-8')\n }\n files.push(rel(settingsPath))\n\n return { files }\n}\n","import type { FormColumn, FormField } from '../../types.js'\n\n// ============================================================================\n// Column Definition Helper\n// ============================================================================\n\nfunction generateColumnDef(col: FormColumn): string {\n const sortableHeader = col.sortable\n ? `header: ({ column }) => (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${col.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )`\n : `header: '${col.header}'`\n\n let cellDef: string\n switch (col.type) {\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${col.accessorKey}') as string\n return email ? <a href={\\`mailto:\\${email}\\`} className=\"text-primary hover:underline\">{email}</a> : '-'\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = row.getValue('${col.accessorKey}') as string\n return date ? new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '-'\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as string\n return <Badge variant=\"outline\">{value || 'N/A'}</Badge>\n }`\n break\n case 'number':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as number\n return <div className=\"text-right\">{value !== null && value !== undefined ? value : '-'}</div>\n }`\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as string\n return <div>{value || '-'}</div>\n }`\n }\n\n return ` {\n accessorKey: '${col.accessorKey}',\n ${sortableHeader},\n ${cellDef}\n }`\n}\n\n// ============================================================================\n// Columns Generator\n// ============================================================================\n\nexport function generateColumns(\n fields: FormField[],\n pascal: string,\n kebab: string,\n camel: string,\n customColumns?: FormColumn[]\n): string {\n const hasBadge = customColumns?.some((c) => c.type === 'badge') ?? false\n\n const columnDefs = customColumns\n ? customColumns.map((col) => generateColumnDef(col)).join(',\\n')\n : fields\n .filter((f) => f.name)\n .map((f) => {\n const accessor = f.name!\n return ` {\n accessorKey: '${accessor}',\n header: ({ column }) => (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${f.label}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n ),\n cell: ({ row }) => {\n const value = row.getValue('${accessor}')\n return <div>${f.type === 'textarea' ? \"{value ? String(value).substring(0, 100) + (String(value).length > 100 ? '...' : '') : '-'}\" : \"{String(value ?? '-')}\"}</div>\n }\n }`\n })\n .join(',\\n')\n\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { delete${pascal}Submission } from '@cms/actions/${kebab}-form'\n${hasBadge ? \"import { Badge } from '@cms/components/ui/badge'\" : ''}\nimport { Button } from '@cms/components/ui/button'\nimport { Checkbox } from '@cms/components/ui/checkbox'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@cms/components/ui/alert-dialog'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ArrowUpDown, Eye, Trash } from 'lucide-react'\nimport Link from 'next/link'\nimport { useState, useTransition } from 'react'\nimport { toast } from 'sonner'\n\nfunction DeleteAction({ id }: { id: number }) {\n const [open, setOpen] = useState(false)\n const [isPending, startTransition] = useTransition()\n const queryClient = useQueryClient()\n\n const handleDelete = () => {\n startTransition(async () => {\n try {\n const result = await delete${pascal}Submission(id)\n if (result.success) {\n toast.success('Submission deleted successfully')\n queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submission')\n }\n } catch {\n toast.error('An error occurred')\n }\n })\n }\n\n return (\n <AlertDialog open={open} onOpenChange={setOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"icon\" className=\"size-8\">\n <Trash className=\"size-3\" />\n <span className=\"sr-only\">Delete</span>\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently delete this submission.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e: React.MouseEvent) => { e.preventDefault(); handleDelete() }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n\nexport const columns: ColumnDef<${pascal}SubmissionData>[] = [\n {\n id: 'select',\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')}\n onCheckedChange={(value: boolean) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value: boolean) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableHiding: false\n },\n${columnDefs},\n {\n id: 'actions',\n header: () => <div className=\"text-right\">Actions</div>,\n cell: ({ row }) => {\n const submission = row.original\n return (\n <div className=\"flex justify-end items-center gap-2\">\n <Button variant=\"outline\" size=\"icon\" className=\"size-8\" asChild>\n <Link href={\\`/cms/forms/${kebab}/\\${submission.id}/view\\`}>\n <Eye className=\"size-3\" />\n <span className=\"sr-only\">View</span>\n </Link>\n </Button>\n <DeleteAction id={submission.id} />\n </div>\n )\n }\n }\n]\n`\n}\n","export function generatePage(pascal: string, kebab: string): string {\n return `import { Suspense } from 'react'\nimport { ${pascal}SubmissionsPageContent } from './${kebab}-submissions-page-content'\nimport { columns } from './columns'\n\nexport default function Page() {\n return (\n <Suspense fallback={<div className=\"p-6\">Loading...</div>}>\n <${pascal}SubmissionsPageContent columns={columns} />\n </Suspense>\n )\n}\n`\n}\n","export function generatePageContent(pascal: string, kebab: string, camel: string, label: string): string {\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { deleteBulk${pascal}Submissions } from '@cms/actions/${kebab}-form'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@cms/components/ui/alert-dialog'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ChevronLeft, Search, Settings, Trash2 } from 'lucide-react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { parseAsString, useQueryState } from 'nuqs'\nimport { startTransition, useCallback, useState, useTransition } from 'react'\nimport { toast } from 'sonner'\nimport { ${pascal}SubmissionsTable } from './${kebab}-submissions-table'\n\ninterface ${pascal}SubmissionsPageContentProps<TValue> {\n columns: ColumnDef<${pascal}SubmissionData, TValue>[]\n}\n\nexport function ${pascal}SubmissionsPageContent<TValue>({\n columns,\n}: ${pascal}SubmissionsPageContentProps<TValue>) {\n const router = useRouter()\n const queryClient = useQueryClient()\n const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n const [selectedIds, setSelectedIds] = useState<number[]>([])\n const [deleteOpen, setDeleteOpen] = useState(false)\n const [isPending, startDeleteTransition] = useTransition()\n\n const searchAction = useCallback(\n async (formData: FormData) => {\n const value = formData.get('search') as string\n startTransition(() => {\n setSearch(value || null)\n })\n },\n [setSearch]\n )\n\n const handleBulkDelete = () => {\n startDeleteTransition(async () => {\n try {\n const result = await deleteBulk${pascal}Submissions(selectedIds)\n if (result.success) {\n toast.success(\\`\\${selectedIds.length} submission\\${selectedIds.length > 1 ? 's' : ''} deleted\\`)\n queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n setSelectedIds([])\n setDeleteOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submissions')\n }\n } catch {\n toast.error('An error occurred')\n }\n })\n }\n\n return (\n <>\n <PageHeader title=\"${label}\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} search={<form action={searchAction} className=\"flex items-center gap-2 relative\">\n <Search className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n key={search}\n name=\"search\"\n placeholder=\"Search submissions...\"\n defaultValue={search}\n className=\"w-64 pl-9 bg-white rounded-full\"\n />\n </form>} actions={<div className=\"flex items-center gap-2\">\n {selectedIds.length > 0 && (\n <AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"default\">\n <Trash2 className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Delete {selectedIds.length}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? 'submission' : 'submissions'}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e: React.MouseEvent) => { e.preventDefault(); handleBulkDelete() }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n <Button variant=\"outline\" asChild>\n <Link href=\"/cms/forms/${kebab}/settings\">\n <Settings className=\"size-3.5\" />\n Settings\n </Link>\n </Button>\n </div>} />\n <main className=\"space-y-4 p-6\">\n <${pascal}SubmissionsTable\n columns={columns}\n selectedIds={selectedIds}\n setSelectedIds={setSelectedIds}\n search={search}\n />\n </main>\n </>\n )\n}\n`\n}\n","export function generateSettingsPage(pascal: string, kebab: string, label: string): string {\n return `'use client'\n\nimport {\n getFormSettings,\n testFormWebhook,\n upsertFormSettings,\n} from '@cms/actions/form-settings'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\nimport { Label } from '@cms/components/ui/label'\nimport { Switch } from '@cms/components/ui/switch'\nimport { Textarea } from '@cms/components/ui/textarea'\nimport { ChevronLeft, Loader2 } from 'lucide-react'\nimport { useRouter } from 'next/navigation'\nimport { useEffect, useState, useTransition } from 'react'\nimport { toast } from 'sonner'\n\nexport default function ${pascal}SettingsPage() {\n const router = useRouter()\n const [notificationEmails, setNotificationEmails] = useState('')\n const [webhookUrl, setWebhookUrl] = useState('')\n const [webhookEnabled, setWebhookEnabled] = useState(false)\n const [isSaving, startSaveTransition] = useTransition()\n const [isTesting, startTestTransition] = useTransition()\n const [loaded, setLoaded] = useState(false)\n\n useEffect(() => {\n getFormSettings('${kebab}').then((settings) => {\n if (settings) {\n setNotificationEmails(settings.notificationEmails ?? '')\n setWebhookUrl(settings.webhookUrl ?? '')\n setWebhookEnabled(settings.webhookEnabled)\n }\n setLoaded(true)\n })\n }, [])\n\n const handleSave = () => {\n startSaveTransition(async () => {\n const result = await upsertFormSettings('${kebab}', {\n notificationEmails: notificationEmails || null,\n webhookUrl: webhookUrl || null,\n webhookEnabled,\n })\n if (result.success) {\n toast.success('Settings saved successfully')\n } else {\n toast.error(result.error || 'Failed to save settings')\n }\n })\n }\n\n const handleTestWebhook = () => {\n startTestTransition(async () => {\n const result = await testFormWebhook('${kebab}')\n if (result.success) {\n toast.success('Test webhook sent successfully')\n } else {\n toast.error(result.error || 'Failed to send test webhook')\n }\n })\n }\n\n if (!loaded) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n </div>\n )\n }\n\n return (\n <>\n <PageHeader title=\"${label} Settings\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} />\n <div className=\"space-y-6 rounded-lg border p-6 mx-6 mt-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"notificationEmails\">Notification Emails</Label>\n <Textarea\n id=\"notificationEmails\"\n placeholder=\"email@example.com, another@example.com\"\n value={notificationEmails}\n onChange={(e) => setNotificationEmails(e.target.value)}\n rows={3}\n />\n <p className=\"text-xs text-muted-foreground\">\n Comma-separated list of email addresses to notify on new submissions.\n </p>\n </div>\n\n <div className=\"space-y-4 border-t pt-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"webhookUrl\">Webhook URL</Label>\n <Input\n id=\"webhookUrl\"\n type=\"url\"\n placeholder=\"https://hooks.example.com/endpoint\"\n value={webhookUrl}\n onChange={(e) => setWebhookUrl(e.target.value)}\n />\n <p className=\"text-xs text-muted-foreground\">\n Receive a POST request with form data on each submission.\n </p>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n <Switch\n id=\"webhookEnabled\"\n checked={webhookEnabled}\n onCheckedChange={setWebhookEnabled}\n />\n <Label htmlFor=\"webhookEnabled\">Enable Webhook</Label>\n </div>\n\n {webhookUrl && webhookEnabled && (\n <Button\n variant=\"outline\"\n onClick={handleTestWebhook}\n disabled={isTesting}\n >\n {isTesting ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Sending...\n </>\n ) : (\n 'Test Webhook'\n )}\n </Button>\n )}\n </div>\n\n <div className=\"border-t pt-6\">\n <Button onClick={handleSave} disabled={isSaving}>\n {isSaving ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Saving...\n </>\n ) : (\n 'Save Settings'\n )}\n </Button>\n </div>\n </div>\n </>\n )\n}\n`\n}\n","export function generateTable(pascal: string, kebab: string, label: string): string {\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { use${pascal}Submissions } from '@cms/hooks/use-${kebab}-form'\nimport { Button } from '@cms/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@cms/components/ui/select'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@cms/components/ui/table'\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type SortingState,\n useReactTable,\n type VisibilityState,\n} from '@tanstack/react-table'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport { useCallback, useMemo, useState } from 'react'\n\nconst PAGE_SIZE_OPTIONS = [\n { value: '10', label: '10' },\n { value: '20', label: '20' },\n { value: '50', label: '50' },\n { value: '100', label: '100' },\n { value: 'all', label: 'All' },\n]\n\ninterface ${pascal}SubmissionsTableProps<TValue> {\n columns: ColumnDef<${pascal}SubmissionData, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string\n}\n\nexport function ${pascal}SubmissionsTable<TValue>({\n columns,\n selectedIds,\n setSelectedIds,\n search,\n}: ${pascal}SubmissionsTableProps<TValue>) {\n const [sorting, setSorting] = useState<SortingState>([])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n const [pageIndex, setPageIndex] = useQueryState('page', parseAsInteger.withDefault(0))\n const [pageSize, setPageSize] = useQueryState('size', parseAsInteger.withDefault(10))\n\n const effectivePageSize = pageSize === -1 ? Number.MAX_SAFE_INTEGER : pageSize\n\n const handlePageSizeChange = useCallback(\n (value: string) => {\n if (value === 'all') {\n setPageSize(-1)\n } else {\n setPageSize(Number.parseInt(value, 10))\n }\n setPageIndex(0)\n },\n [setPageSize, setPageIndex]\n )\n\n const { data, error, isPending } = use${pascal}Submissions(search)\n\n const rowSelection = useMemo(() => {\n const selection: Record<string, boolean> = {}\n const submissions = data?.submissions ?? []\n submissions.forEach((sub, idx) => {\n if (selectedIds.includes(sub.id)) {\n selection[idx.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.submissions])\n\n const handleRowSelectionChange = useCallback(\n (updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)) => {\n const submissions = data?.submissions ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n const newIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => submissions[Number.parseInt(key, 10)]?.id)\n .filter(Boolean) as number[]\n setSelectedIds(newIds)\n },\n [data?.submissions, rowSelection, setSelectedIds]\n )\n\n const table = useReactTable({\n data: data?.submissions ?? [],\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: handleRowSelectionChange,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n pagination: { pageIndex, pageSize: effectivePageSize },\n },\n })\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border overflow-hidden\">\n <Table>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <TableHead key={header.id}>\n {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isPending ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center text-muted-foreground\">\n Loading ${label} submissions...\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center text-destructive\">\n Error: {error.message}\n </TableCell>\n </TableRow>\n ) : table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n No submissions found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <p className=\"text-sm text-muted-foreground\">Rows per page</p>\n <Select\n value={pageSize === -1 ? 'all' : pageSize.toString()}\n onValueChange={handlePageSizeChange}\n >\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent side=\"top\">\n {PAGE_SIZE_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center space-x-2\">\n <div className=\"flex w-[100px] items-center justify-center text-sm font-medium\">\n Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setPageIndex(Math.max(0, pageIndex - 1))} disabled={!table.getCanPreviousPage()}>\n Previous\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setPageIndex(pageIndex + 1)} disabled={!table.getCanNextPage()}>\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n}\n","import type { FormField } from '../../types.js'\n\nexport function generateViewPage(\n pascal: string,\n kebab: string,\n fields: FormField[],\n label: string,\n includeDynamic: boolean\n): string {\n const fieldItems = fields\n .filter((f) => f.name)\n .map((f) => {\n const name = f.name!\n const lbl = f.label\n\n if (f.type === 'email') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">\n {submission.${name} ? (\n <a href={\\`mailto:\\${submission.${name}}\\`} className=\"text-primary hover:underline\">{submission.${name}}</a>\n ) : '-'}\n </p>\n </div>`\n }\n if (f.type === 'textarea') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm whitespace-pre-wrap\">{submission.${name} || '-'}</p>\n </div>`\n }\n if (f.type === 'checkbox') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ? 'Yes' : 'No'}</p>\n </div>`\n }\n if (f.type === 'date') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ? new Date(submission.${name}).toLocaleDateString() : '-'}</p>\n </div>`\n }\n if (f.type === 'url') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">\n {submission.${name} ? (\n <a href={submission.${name}} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-primary hover:underline break-all\">{submission.${name}}</a>\n ) : '-'}\n </p>\n </div>`\n }\n if (f.type === 'list' || f.type === 'multiselect') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <div className=\"text-sm\">\n {Array.isArray(submission.${name}) && submission.${name}.length > 0 ? (\n <ul className=\"list-disc list-inside space-y-1\">\n {submission.${name}.map((item: Record<string, unknown>, idx: number) => (\n <li key={idx}>{typeof item === 'string' ? item : Object.entries(item).map(([k, v]) => \\`\\${k}: \\${v}\\`).join(', ')}</li>\n ))}\n </ul>\n ) : '-'}\n </div>\n </div>`\n }\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ?? '-'}</p>\n </div>`\n })\n .join('\\n')\n\n const customFieldsSection = includeDynamic\n ? `\n {submission.customFields && Object.keys(submission.customFields).length > 0 && (\n <div className=\"space-y-3 border-t pt-4\">\n <p className=\"text-sm font-semibold text-muted-foreground\">Custom Fields</p>\n {Object.entries(submission.customFields).map(([key, value]) => (\n <div key={key} className=\"space-y-1\">\n <p className=\"text-sm font-medium capitalize\">{key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <p className=\"text-sm\">{value !== null && value !== undefined ? String(value) : '-'}</p>\n </div>\n ))}\n </div>\n )}`\n : ''\n\n return `import { get${pascal}Submission } from '@cms/actions/${kebab}-form'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { connection } from 'next/server'\n\ninterface PageProps {\n params: Promise<{ id: string }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n await connection()\n const submission = await get${pascal}Submission(Number.parseInt(id, 10))\n\n if (!submission) {\n notFound()\n }\n\n return (\n <>\n <PageHeader title=\"${label} Submission\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/forms/${kebab}\"><ChevronLeft /></Link></Button>} />\n <div className=\"rounded-lg border p-6 mx-6 mt-6 space-y-4\">\n${fieldItems}${customFieldsSection}\n <div className=\"space-y-1 border-t pt-4\">\n <p className=\"text-sm font-medium text-muted-foreground\">Submitted At</p>\n <p className=\"text-sm\">\n {new Date(submission.submittedAt).toLocaleString('en-US', {\n month: 'long', day: 'numeric', year: 'numeric',\n hour: 'numeric', minute: '2-digit'\n })}\n </p>\n </div>\n </div>\n </>\n )\n}\n`\n}\n","/**\n * Form navigation generator: adds form submissions entry to cms/data/navigation.ts\n * Each form gets a flat nav item with group: 'Forms'\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { FormSchema, GeneratorOptions } from '../types.js'\nimport { toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface NavItem {\n label: string\n href: string\n icon?: string\n group?: string\n}\n\n// ============================================================================\n// Parser (mirrors entity navigation generator)\n// ============================================================================\n\nfunction parseNavigationFile(content: string): { items: NavItem[]; iconImports: string[] } {\n const iconImportMatch = content.match(/import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]lucide-react['\"]/)\n const iconImports: string[] = iconImportMatch\n ? iconImportMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s && s !== 'LucideIcon')\n : []\n\n const arrayBlock = extractTopLevelArray(content)\n if (!arrayBlock) return { items: [], iconImports }\n\n return { items: parseItemsBlock(arrayBlock), iconImports }\n}\n\nfunction extractTopLevelArray(content: string): string | null {\n const marker = content.indexOf('cmsNavigation')\n if (marker === -1) return null\n\n const eqSign = content.indexOf('=', marker)\n if (eqSign === -1) return null\n const openBracket = content.indexOf('[', eqSign)\n if (openBracket === -1) return null\n\n let depth = 0\n for (let i = openBracket; i < content.length; i++) {\n if (content[i] === '[') depth++\n if (content[i] === ']') depth--\n if (depth === 0) {\n return content.slice(openBracket + 1, i)\n }\n }\n return null\n}\n\nfunction parseItemsBlock(block: string): NavItem[] {\n const items: NavItem[] = []\n let depth = 0\n let current = ''\n let inObj = false\n\n for (const char of block) {\n if (char === '{') {\n if (depth === 0) inObj = true\n depth++\n current += char\n } else if (char === '}') {\n depth--\n current += char\n if (depth === 0 && inObj) {\n const item = parseSingleItem(current)\n if (item) items.push(item)\n current = ''\n inObj = false\n }\n } else if (inObj) {\n current += char\n }\n }\n\n return items\n}\n\nfunction parseSingleItem(str: string): NavItem | null {\n const labelMatch = str.match(/label:\\s*['\"]([^'\"]+)['\"]/)\n const hrefMatch = str.match(/href:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = str.match(/icon:\\s*(\\w+)/)\n const groupMatch = str.match(/group:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!labelMatch || !hrefMatch) return null\n\n const item: NavItem = { label: labelMatch[1], href: hrefMatch[1] }\n if (iconMatch) item.icon = iconMatch[1]\n if (groupMatch) item.group = groupMatch[1]\n\n return item\n}\n\n// ============================================================================\n// Code Generator (mirrors entity navigation generator)\n// ============================================================================\n\nfunction generateNavigationCode(items: NavItem[], iconImports: string[]): string {\n const lines: string[] = []\n\n lines.push(\"import type { LucideIcon } from 'lucide-react'\")\n lines.push(`import { ${iconImports.join(', ')} } from 'lucide-react'`)\n lines.push('')\n lines.push('export interface CmsNavigationItem {')\n lines.push(' label: string')\n lines.push(' href: string')\n lines.push(' icon?: LucideIcon')\n lines.push(' group?: string')\n lines.push('}')\n lines.push('')\n lines.push('export const cmsNavigation: CmsNavigationItem[] = [')\n\n for (let i = 0; i < items.length; i++) {\n appendItem(lines, items[i], i === items.length - 1)\n }\n\n lines.push(']')\n lines.push('')\n\n return lines.join('\\n')\n}\n\nfunction appendItem(lines: string[], item: NavItem, isLast: boolean): void {\n lines.push(' {')\n lines.push(` label: '${item.label}',`)\n\n const hasMore = item.icon != null || item.group != null\n lines.push(` href: '${item.href}'${hasMore ? ',' : ''}`)\n\n if (item.icon && item.group) {\n lines.push(` icon: ${item.icon},`)\n lines.push(` group: '${item.group}'`)\n } else if (item.icon) {\n lines.push(` icon: ${item.icon}`)\n } else if (item.group) {\n lines.push(` group: '${item.group}'`)\n }\n\n lines.push(` }${isLast ? '' : ','}`)\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface FormNavigationResult {\n files: string[]\n}\n\n/**\n * Update cms/data/navigation.ts to add form under \"Forms\" group\n */\nexport function updateFormNavigation(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): FormNavigationResult {\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n\n let items: NavItem[] = []\n let iconImports: string[] = []\n\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const parsed = parseNavigationFile(content)\n items = parsed.items\n iconImports = parsed.iconImports\n }\n\n // Create form nav item with group: 'Forms'\n const kebab = toKebabCase(schema.name)\n const formHref = `/cms/forms/${kebab}`\n const existingIndex = items.findIndex((item) => item.href === formHref)\n\n const newItem: NavItem = {\n label: schema.label,\n href: formHref,\n icon: 'Inbox',\n group: 'Forms'\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n items[existingIndex] = newItem\n } else {\n return { files: [] }\n }\n } else {\n items.push(newItem)\n }\n\n // Reorganize: Dashboard first, then ungrouped alphabetical, then grouped alphabetical\n const dashboard = items.find((item) => item.href === '/cms')\n const others = items.filter((item) => item.href !== '/cms')\n others.sort((a, b) => {\n if (!a.group && b.group) return -1\n if (a.group && !b.group) return 1\n if (a.group && b.group && a.group !== b.group) return a.group.localeCompare(b.group)\n return a.label.localeCompare(b.label)\n })\n\n items = [...(dashboard ? [dashboard] : []), ...others]\n\n // Ensure required icon is imported\n if (!iconImports.includes('Inbox')) {\n iconImports.push('Inbox')\n }\n iconImports.sort()\n\n // Write\n const dir = path.dirname(navFilePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n fs.writeFileSync(navFilePath, generateNavigationCode(items, iconImports), 'utf-8')\n\n return { files: [path.join(cmsDir, 'data', 'navigation.ts')] }\n}\n","/**\n * Form pipeline step 2: Server actions for form submissions\n * Split into individual files with barrel index.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields } from '../../core/field-helpers/index.js'\nimport type { FormField, FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\n\ninterface StepResult {\n files: string[]\n}\n\nfunction generateMailchimpCode(schema: FormSchema, fields: FormField[]): string {\n if (!schema.mailchimp) return ''\n\n let emailFieldName: string\n if (typeof schema.mailchimp === 'object' && schema.mailchimp.emailField) {\n emailFieldName = schema.mailchimp.emailField\n } else {\n const emailField = fields.find((f) => f.type === 'email')\n if (!emailField || !emailField.name) {\n console.warn(\n `Warning: Form \"${schema.name}\" has mailchimp enabled but no email field found. Skipping.`\n )\n return ''\n }\n emailFieldName = emailField.name\n }\n\n return `\\n // Add to Mailchimp audience (fire-and-forget, non-blocking)\n addToMailchimpAudience(data.${emailFieldName})`\n}\n\nexport function generateFormActions(\n schema: FormSchema,\n cwd: string,\n actionsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const tableName = `${toCamelCase(formName)}Submissions`\n const pascal = toPascalCase(formName)\n const kebab = toKebabCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, `${kebab}-form`)\n const oldFilePath = path.join(absActionsDir, `${kebab}-form.ts`)\n\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n // Build TypeScript interface fields\n const dataFields = fields\n .map((f) => {\n let tsType = 'string'\n if (f.type === 'number') tsType = 'number'\n else if (f.type === 'checkbox') tsType = 'boolean'\n else if (f.type === 'multiselect') tsType = 'string[]'\n else if (f.type === 'list') {\n tsType = f.fields && f.fields.length > 0 ? 'Record<string, unknown>[]' : 'string[]'\n }\n const isReq = f.required && !f.condition\n const opt = isReq ? '' : '?'\n const nullable = isReq ? '' : ' | null'\n return ` ${f.name}${opt}: ${tsType}${nullable}`\n })\n .join('\\n')\n\n const validation = fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) =>\n `if (!data.${f.name}) {\\n return { success: false, error: '${f.label} is required' }\\n }`\n )\n .join('\\n ')\n\n const mailchimpImport = schema.mailchimp\n ? `\\nimport { addToMailchimpAudience } from '@cms/utils/mailchimp'`\n : ''\n const mailchimpCall = generateMailchimpCode(schema, fields)\n\n // --- types.ts ---\n const typesContent = `export interface ${pascal}SubmissionData {\n id: number\n${dataFields}\n ipAddress: string | null\n userAgent: string | null\n submittedAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface ${pascal}SubmissionsResponse {\n submissions: ${pascal}SubmissionData[]\n total: number\n}\n\nexport interface Create${pascal}SubmissionInput {\n${dataFields}\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Create${pascal}SubmissionResult {\n success: boolean\n error?: string\n submission?: ${pascal}SubmissionData\n}\n\nexport interface Delete${pascal}SubmissionResult {\n success: boolean\n error?: string\n count?: number\n}\n`\n\n // --- get-{kebab}-submissions.ts ---\n const getSubmissionsContent = `'use server'\n\nimport { desc } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { ${pascal}SubmissionsResponse, ${pascal}SubmissionData } from './types'\n\nexport async function get${pascal}Submissions(): Promise<${pascal}SubmissionsResponse> {\n try {\n const submissions = await db.select().from(${tableName}).orderBy(desc(${tableName}.submittedAt))\n return {\n submissions: submissions as ${pascal}SubmissionData[],\n total: submissions.length\n }\n } catch (error) {\n console.error('Error fetching ${formName} submissions:', error)\n throw new Error('Failed to fetch ${formName} submissions')\n }\n}\n`\n\n // --- get-{kebab}-submission.ts ---\n const getSubmissionContent = `'use server'\n\nimport { eq } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { ${pascal}SubmissionData } from './types'\n\nexport async function get${pascal}Submission(id: number): Promise<${pascal}SubmissionData | null> {\n try {\n const [submission] = await db\n .select()\n .from(${tableName})\n .where(eq(${tableName}.id, id))\n .limit(1)\n return (submission as ${pascal}SubmissionData) ?? null\n } catch (error) {\n console.error(\\`Error fetching ${formName} submission \\${id}:\\`, error)\n throw new Error('Failed to fetch ${formName} submission')\n }\n}\n`\n\n // --- create-{kebab}-submission.ts ---\n const createContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport { getFormSettings } from '@cms/actions/form-settings'\nimport { sendWebhook } from '@cms/utils/webhook'${mailchimpImport}\nimport type { Create${pascal}SubmissionInput, Create${pascal}SubmissionResult, ${pascal}SubmissionData } from './types'\n\nexport async function create${pascal}Submission(\n data: Create${pascal}SubmissionInput\n): Promise<Create${pascal}SubmissionResult> {\n try {\n ${validation}\n\n const [submission] = await db\n .insert(${tableName})\n .values({\n ...data,\n submittedAt: new Date().toISOString()\n })\n .returning()\n\n // Resolve notification emails from form settings or env var\n const settings = await getFormSettings('${formName}')\n const notificationEmails = settings?.notificationEmails\n ? settings.notificationEmails.split(',').map((e: string) => e.trim()).filter(Boolean)\n : process.env.NOTIFICATION_EMAIL\n ? [process.env.NOTIFICATION_EMAIL]\n : []\n\n if (notificationEmails.length > 0) {\n // TODO: Send notification email using your email provider (e.g. Resend)\n console.log(\\`[${formName}] New submission — notify: \\${notificationEmails.join(', ')}\\`)\n }\n\n // Send webhook if enabled\n if (settings?.webhookEnabled && settings?.webhookUrl) {\n sendWebhook(settings.webhookUrl, {\n form_name: '${formName}',\n submission_id: submission.id,\n ...data,\n submitted_at: (submission as ${pascal}SubmissionData).submittedAt,\n })\n }${mailchimpCall}\n\n return {\n success: true,\n submission: submission as ${pascal}SubmissionData\n }\n } catch (error) {\n console.error('Error creating ${formName} submission:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create ${formName} submission'\n }\n }\n}\n`\n\n // --- delete-{kebab}-submission.ts ---\n const deleteContent = `'use server'\n\nimport { eq } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { Delete${pascal}SubmissionResult } from './types'\n\nexport async function delete${pascal}Submission(id: number): Promise<Delete${pascal}SubmissionResult> {\n try {\n await db.delete(${tableName}).where(eq(${tableName}.id, id))\n return { success: true }\n } catch (error) {\n console.error(\\`Error deleting ${formName} submission \\${id}:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${formName} submission'\n }\n }\n}\n`\n\n // --- delete-bulk-{kebab}-submissions.ts ---\n const deleteBulkContent = `'use server'\n\nimport { eq, or } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { Delete${pascal}SubmissionResult } from './types'\n\nexport async function deleteBulk${pascal}Submissions(ids: number[]): Promise<Delete${pascal}SubmissionResult> {\n try {\n if (ids.length === 0) return { success: true, count: 0 }\n await db.delete(${tableName}).where(\n or(...ids.map(id => eq(${tableName}.id, id)))\n )\n return { success: true, count: ids.length }\n } catch (error) {\n console.error(\\`Error bulk deleting ${formName} submissions:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to bulk delete ${formName} submissions'\n }\n }\n}\n`\n\n // --- export-{kebab}-submissions-csv.ts ---\n const exportCsvContent = `'use server'\n\nimport { get${pascal}Submissions } from './get-${kebab}-submissions'\n\nexport async function export${pascal}SubmissionsCSV(): Promise<string> {\n const { submissions } = await get${pascal}Submissions()\n if (submissions.length === 0) return ''\n const headers = Object.keys(submissions[0]).join(',')\n const rows = submissions.map((sub) =>\n Object.values(sub)\n .map((val: unknown) => {\n if (val === null || val === undefined) return ''\n const str = String(val)\n if (str.includes(',') || str.includes('\"') || str.includes('\\\\n')) {\n return \\`\"\\${str.replace(/\"/g, '\"\"')}\"\\`\n }\n return str\n })\n .join(',')\n )\n return [headers, ...rows].join('\\\\n')\n}\n`\n\n // --- export-{kebab}-submissions-json.ts ---\n const exportJsonContent = `'use server'\n\nimport { get${pascal}Submissions } from './get-${kebab}-submissions'\n\nexport async function export${pascal}SubmissionsJSON(): Promise<string> {\n const { submissions } = await get${pascal}Submissions()\n return JSON.stringify(submissions, null, 2)\n}\n`\n\n // --- index.ts (barrel) ---\n const barrelContent = `export type { ${pascal}SubmissionData, ${pascal}SubmissionsResponse, Create${pascal}SubmissionInput, Create${pascal}SubmissionResult, Delete${pascal}SubmissionResult } from './types'\nexport { get${pascal}Submissions } from './get-${kebab}-submissions'\nexport { get${pascal}Submission } from './get-${kebab}-submission'\nexport { create${pascal}Submission } from './create-${kebab}-submission'\nexport { delete${pascal}Submission } from './delete-${kebab}-submission'\nexport { deleteBulk${pascal}Submissions } from './delete-bulk-${kebab}-submissions'\nexport { export${pascal}SubmissionsCSV } from './export-${kebab}-submissions-csv'\nexport { export${pascal}SubmissionsJSON } from './export-${kebab}-submissions-json'\n`\n\n // Write all files\n const files = [\n { name: 'types.ts', content: typesContent },\n { name: `get-${kebab}-submissions.ts`, content: getSubmissionsContent },\n { name: `get-${kebab}-submission.ts`, content: getSubmissionContent },\n { name: `create-${kebab}-submission.ts`, content: createContent },\n { name: `delete-${kebab}-submission.ts`, content: deleteContent },\n { name: `delete-bulk-${kebab}-submissions.ts`, content: deleteBulkContent },\n { name: `export-${kebab}-submissions-csv.ts`, content: exportCsvContent },\n { name: `export-${kebab}-submissions-json.ts`, content: exportJsonContent },\n { name: 'index.ts', content: barrelContent }\n ]\n\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.relative(cwd, path.join(dirPath, f.name))) }\n}\n","/**\n * Multi-step wizard form component generator\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields, getStepFieldNames } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toKebabCase } from '../../utils/string.js'\nimport {\n type StepResult,\n resolveUiImport,\n escapeJsx,\n renderFieldsJSX,\n buildZodFields,\n buildDefaultValues,\n buildFieldArrayDecls,\n buildWatchDecls,\n getListFields,\n} from './form-component-shared.js'\n\nexport function generateMultiStepForm(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const kebab = toKebabCase(formName)\n const steps = schema.steps!\n\n const filePath = path.join(cwd, cmsDir, 'components', 'forms', `${kebab}-form.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n // All fields flattened (for Zod schema + defaults)\n const allFields = getAllFormSchemaFields(schema)\n const zodFields = buildZodFields(allFields)\n const defaults = buildDefaultValues(allFields)\n\n // List fields and watch declarations are global\n const listFields = getListFields(allFields)\n const hasListFields = listFields.length > 0\n const { setup: watchSetup } = buildWatchDecls(allFields)\n\n const rhfImport = hasListFields\n ? `import { useFieldArray, useForm } from 'react-hook-form'`\n : `import { useForm } from 'react-hook-form'`\n const fieldArraySetup = hasListFields ? `\\n${buildFieldArrayDecls(listFields)}\\n` : ''\n\n // Build STEPS constant\n const stepsConst = buildStepsConstant(steps, schema)\n\n // Build per-step content blocks\n const stepContentBlocks = steps\n .map((step, index) => {\n const fieldsJSX = renderFieldsJSX(step.fields)\n return ` {currentStep === ${index} && (\\n <>\\n${fieldsJSX}\\n </>\\n )}`\n })\n .join('\\n')\n\n const submitText = schema.submitButtonText || 'Submit'\n const successMessage = escapeJsx(schema.successMessage || 'Form submitted successfully!')\n\n // Resolve UI imports\n const hasRadio = allFields.some((f) => f.type === 'radio')\n const hasFileUpload = allFields.some((f) => f.type === 'file' || f.type === 'upload')\n const buttonImport = resolveUiImport(cwd, 'button')\n const formImport = resolveUiImport(cwd, 'form')\n const inputImport = resolveUiImport(cwd, 'input')\n const textareaImport = resolveUiImport(cwd, 'textarea')\n const selectImport = resolveUiImport(cwd, 'select')\n const radioGroupImport = resolveUiImport(cwd, 'radio-group')\n const mediaUploadImport = resolveUiImport(cwd, 'media-upload-field')\n\n const content = buildComponentSource({\n pascal,\n kebab,\n rhfImport,\n hasRadio,\n hasFileUpload,\n hasListFields,\n buttonImport,\n formImport,\n inputImport,\n textareaImport,\n selectImport,\n radioGroupImport,\n mediaUploadImport,\n zodFields,\n defaults,\n stepsConst,\n fieldArraySetup,\n watchSetup,\n stepContentBlocks,\n submitText,\n successMessage,\n })\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n\nfunction buildStepsConstant(\n steps: NonNullable<FormSchema['steps']>,\n schema: FormSchema\n): string {\n const entries = steps.map((step) => {\n const fieldNames = getStepFieldNames(step)\n const fieldsStr = fieldNames.map((n) => `'${n}'`).join(', ')\n const desc = step.description ? `, description: '${escapeQuotes(step.description)}'` : ''\n return ` { name: '${step.name}', label: '${escapeQuotes(step.label)}'${desc}, fields: [${fieldsStr}] }`\n })\n return `const STEPS = [\\n${entries.join(',\\n')}\\n]`\n}\n\nfunction escapeQuotes(str: string): string {\n return str.replace(/'/g, \"\\\\'\")\n}\n\ninterface ComponentParts {\n pascal: string\n kebab: string\n rhfImport: string\n hasRadio: boolean\n hasFileUpload: boolean\n hasListFields: boolean\n buttonImport: string\n formImport: string\n inputImport: string\n textareaImport: string\n selectImport: string\n radioGroupImport: string\n mediaUploadImport: string\n zodFields: string\n defaults: string\n stepsConst: string\n fieldArraySetup: string\n watchSetup: string\n stepContentBlocks: string\n submitText: string\n successMessage: string\n}\n\nfunction buildComponentSource(p: ComponentParts): string {\n const queryClientImport = p.hasFileUpload\n ? `\\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'`\n : ''\n const queryClientSetup = p.hasFileUpload\n ? `\\nconst queryClient = new QueryClient()\\n`\n : ''\n const formComponentDecl = p.hasFileUpload ? `function ${p.pascal}FormInner` : `export function ${p.pascal}Form`\n const exportWrapper = p.hasFileUpload\n ? `\\nexport function ${p.pascal}Form() {\n return (\n <QueryClientProvider client={queryClient}>\n <${p.pascal}FormInner />\n </QueryClientProvider>\n )\n}\\n`\n : ''\n\n return `'use client'\n\nimport { ChevronLeft, ChevronRight${p.hasListFields ? ', Trash2' : ''} } from 'lucide-react'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport { useState } from 'react'\n${p.rhfImport}\nimport { z } from 'zod/v3'${queryClientImport}\nimport { create${p.pascal}Submission } from '@cms/actions/${p.kebab}-form'\nimport { Button } from '${p.buttonImport}'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '${p.formImport}'\nimport { Input } from '${p.inputImport}'${p.hasFileUpload ? `\\nimport { MediaUploadField } from '${p.mediaUploadImport}'` : ''}\n${p.hasRadio ? `import { RadioGroup, RadioGroupItem } from '${p.radioGroupImport}'\\n` : ''}\nimport { Textarea } from '${p.textareaImport}'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '${p.selectImport}'\n\nconst formSchema = z.object({\n${p.zodFields}\n})\n\ntype FormValues = z.infer<typeof formSchema>\n${queryClientSetup}\n${p.stepsConst}\n\n${formComponentDecl}() {\n const [currentStep, setCurrentStep] = useQueryState('step', parseAsInteger.withDefault(0))\n const [submitted, setSubmitted] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const form = useForm<FormValues>({\n defaultValues: {\n${p.defaults}\n },\n })\n\n${p.fieldArraySetup}${p.watchSetup}\n async function handleNext() {\n const stepFields = STEPS[currentStep].fields as (keyof FormValues)[]\n const values = form.getValues()\n form.clearErrors(stepFields)\n let isValid = true\n for (const fieldName of stepFields) {\n const fieldSchema = formSchema.shape[fieldName]\n if (!fieldSchema) continue\n const result = fieldSchema.safeParse(values[fieldName])\n if (!result.success) {\n form.setError(fieldName, { type: 'validate', message: result.error.issues[0].message })\n isValid = false\n }\n }\n if (isValid) {\n setCurrentStep(currentStep + 1)\n }\n }\n\n function handleBack() {\n setCurrentStep(currentStep - 1)\n }\n\n async function onSubmit(values: FormValues) {\n const validation = formSchema.safeParse(values)\n if (!validation.success) {\n for (const issue of validation.error.issues) {\n const fieldName = issue.path[0] as keyof FormValues\n form.setError(fieldName, { type: 'validate', message: issue.message })\n }\n return\n }\n setSubmitting(true)\n try {\n const result = await create${p.pascal}Submission(validation.data)\n if (result.success) {\n setSubmitted(true)\n } else {\n form.setError('root', { message: result.error || 'Something went wrong' })\n }\n } catch {\n form.setError('root', { message: 'Something went wrong. Please try again.' })\n } finally {\n setSubmitting(false)\n }\n }\n\n if (submitted) {\n return (\n <div className=\"rounded-lg border p-6 text-center\">\n <h3 className=\"text-lg font-semibold\">Thank you!</h3>\n <p className=\"mt-2 text-muted-foreground\">${p.successMessage}</p>\n </div>\n )\n }\n\n return (\n <Form {...form}>\n <form onSubmit={(e) => e.preventDefault()} className=\"space-y-8\">\n {/* Step header */}\n <div>\n <h3 className=\"text-lg font-semibold\">{STEPS[currentStep].label}</h3>\n {'description' in STEPS[currentStep] && STEPS[currentStep].description && (\n <p className=\"text-sm text-muted-foreground mt-1\">{STEPS[currentStep].description}</p>\n )}\n </div>\n\n {/* Step content */}\n <div key={currentStep} className=\"animate-in fade-in duration-300 space-y-6\">\n${p.stepContentBlocks}\n </div>\n\n {form.formState.errors.root && (\n <p className=\"text-sm text-destructive\">{form.formState.errors.root.message}</p>\n )}\n\n {/* Navigation */}\n <div className=\"flex justify-between\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleBack}\n disabled={currentStep === 0}\n >\n <ChevronLeft className=\"mr-2 size-4\" />\n Back\n </Button>\n {currentStep < STEPS.length - 1 ? (\n <Button type=\"button\" onClick={handleNext}>\n Next\n <ChevronRight className=\"ml-2 size-4\" />\n </Button>\n ) : (\n <Button type=\"button\" disabled={submitting} onClick={() => onSubmit(form.getValues())}>\n {submitting ? 'Submitting...' : '${p.submitText}'}\n </Button>\n )}\n </div>\n </form>\n </Form>\n )\n}\n${exportWrapper}`\n}\n","/**\n * Shared helpers for form component generation\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { formFieldToZodType } from '../../core/type-mappers/index.js'\nimport type { FormField } from '../../types.js'\nimport { singularize } from '../../utils/string.js'\n\nexport interface StepResult {\n files: string[]\n}\n\n/**\n * Check if a shadcn UI component exists in the user's project.\n * Returns `@/components/ui/<name>` if found, otherwise `@cms/components/ui/<name>`.\n */\nexport function resolveUiImport(cwd: string, componentName: string): string {\n const locations = ['components/ui', 'src/components/ui']\n for (const loc of locations) {\n if (\n fs.existsSync(path.join(cwd, loc, `${componentName}.tsx`)) ||\n fs.existsSync(path.join(cwd, loc, `${componentName}.ts`))\n ) {\n return `@/components/ui/${componentName}`\n }\n }\n return `@cms/components/ui/${componentName}`\n}\n\n/** Escape text for safe use in JSX content */\nexport function escapeJsx(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Flatten form fields, resolving groups and skipping dynamic fields */\nexport function flattenFormFields(fields: FormField[]): FormField[] {\n return fields.flatMap((field) => {\n if (field.type === 'dynamicFields') return []\n if (field.type === 'group' && field.fields) return flattenFormFields(field.fields)\n return field.type === 'group' ? [] : [field]\n })\n}\n\n/** Build Zod schema field entries from form fields */\nexport function buildZodFields(fields: FormField[]): string {\n return fields\n .filter((f) => f.name)\n .map((f) => ` ${f.name}: ${formFieldToZodType(f)}`)\n .join(',\\n')\n}\n\n/** Build default value entries from form fields */\nexport function buildDefaultValues(fields: FormField[]): string {\n return fields\n .filter((f) => f.name)\n .map((f) => {\n if (f.type === 'checkbox') return ` ${f.name}: false`\n if (f.type === 'number') return ` ${f.name}: undefined`\n if (f.type === 'multiselect' || f.type === 'list') return ` ${f.name}: []`\n if (f.type === 'radio' && f.defaultValue !== undefined) return ` ${f.name}: '${f.defaultValue}'`\n if (f.type === 'select' || f.type === 'radio') return ` ${f.name}: undefined`\n if (f.defaultValue !== undefined) return ` ${f.name}: '${f.defaultValue}'`\n return ` ${f.name}: ''`\n })\n .join(',\\n')\n}\n\n/** Build useFieldArray declarations for list fields */\nexport function buildFieldArrayDecls(listFields: FormField[]): string {\n return listFields\n .map(\n (f) =>\n ` const ${f.name}FieldArray = useFieldArray({ control: form.control, name: '${f.name}' })`\n )\n .join('\\n')\n}\n\n/** Build watch variable declarations for showWhen fields */\nexport function buildWatchDecls(fields: FormField[]): { setup: string; hasWatch: boolean } {\n const watchFields = new Set<string>()\n for (const f of fields) {\n if (f.showWhen) {\n watchFields.add(f.showWhen.field)\n }\n }\n if (watchFields.size === 0) return { setup: '', hasWatch: false }\n const decls = Array.from(watchFields)\n .map((wf) => ` const ${wf}Value = form.watch('${wf}')`)\n .join('\\n')\n return { setup: `\\n${decls}\\n`, hasWatch: true }\n}\n\n/** Get list fields that need useFieldArray */\nexport function getListFields(fields: FormField[]): FormField[] {\n return fields.filter(\n (f) => f.name && f.type === 'list' && f.fields && f.fields.length > 0\n )\n}\n\n/**\n * Render an array of form fields to JSX, preserving group layout.\n * Group fields render as a responsive grid wrapper; other fields render normally.\n */\nexport function renderFieldsJSX(fields: FormField[]): string {\n return fields\n .filter((f) => !f.hidden)\n .map((f) => {\n if (f.type === 'dynamicFields') return ''\n if (f.type === 'group' && f.fields) {\n const cols = f.columns || 2\n const innerJSX = renderFieldsJSX(f.fields)\n const groupJSX = ` <div className=\"grid grid-cols-1 md:grid-cols-${cols} gap-4\">\\n${innerJSX}\\n </div>`\n return f.showWhen ? wrapShowWhen(f, groupJSX) : groupJSX\n }\n if (!f.name) return ''\n return wrapShowWhen(f, generateFieldJSX(f))\n })\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/** Wrap field JSX with showWhen conditional if applicable */\nexport function wrapShowWhen(field: FormField, jsx: string): string {\n if (!field.showWhen) return jsx\n const watchVar = `${field.showWhen.field}Value`\n const { value } = field.showWhen\n if (Array.isArray(value)) {\n const vals = value.map((v) => `'${v}'`).join(', ')\n return ` {[${vals}].includes(${watchVar} as string) && (\\n${jsx}\\n )}`\n }\n return ` {${watchVar} === '${value}' && (\\n${jsx}\\n )}`\n}\n\n/** Generate JSX for a single form field */\nexport function generateFieldJSX(field: FormField): string {\n const name = field.name || ''\n const label = escapeJsx(field.label)\n const placeholder = field.placeholder || ''\n const hint = field.hint || ''\n\n const hintJSX = hint ? `\\n <FormDescription>${escapeJsx(hint)}</FormDescription>` : ''\n const hintPlainJSX = hint ? `\\n <p className=\"text-sm text-muted-foreground\">${escapeJsx(hint)}</p>` : ''\n const requiredStar = field.required ? ' <span className=\"text-destructive\">*</span>' : ''\n\n switch (field.type) {\n case 'textarea':\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <Textarea placeholder=\"${placeholder}\" {...field} />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n\n case 'radio':\n if (field.options && field.options.length > 0) {\n const radioItems = field.options\n .map(\n (opt) =>\n ` <FormLabel htmlFor=\"${name}-${opt.value}\" className=\"flex items-center space-x-2 text-sm font-medium leading-none\">\n <RadioGroupItem value=\"${opt.value}\" id=\"${name}-${opt.value}\" />\n <span>${escapeJsx(opt.label)}</span>\n </FormLabel>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem className=\"space-y-3\">\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <RadioGroup onValueChange={field.onChange} defaultValue={field.value} className=\"flex items-center space-x-2\">\n${radioItems}\n </RadioGroup>\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n\n case 'select':\n if (field.options && field.options.length > 0) {\n const optionItems = field.options\n .map(\n (opt) =>\n ` <SelectItem value=\"${opt.value}\">${escapeJsx(opt.label)}</SelectItem>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <Select onValueChange={field.onChange} defaultValue={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"${placeholder || 'Select...'}\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n${optionItems}\n </SelectContent>\n </Select>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n\n case 'checkbox':\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <input\n type=\"checkbox\"\n checked={field.value}\n onChange={field.onChange}\n className=\"mt-1\"\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel>${label}${requiredStar}</FormLabel>${hintJSX}\n <FormMessage />\n </div>\n </FormItem>\n )}\n />`\n\n case 'email':\n return generateTextFieldJSX(name, label, placeholder || 'email@example.com', hintJSX, requiredStar, 'email')\n\n case 'number':\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'number')\n\n case 'date':\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'date')\n\n case 'url':\n return generateTextFieldJSX(name, label, placeholder || 'https://', hintJSX, requiredStar, 'url')\n\n case 'phone':\n return generateTextFieldJSX(name, label, placeholder || '+1 (555) 000-0000', hintJSX, requiredStar, 'tel')\n\n case 'file':\n case 'upload':\n return generateFileUploadFieldJSX(field, name, label, hintJSX, requiredStar)\n\n case 'list':\n return generateListFieldJSX(field, name, label, hintPlainJSX, requiredStar)\n\n default:\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n }\n}\n\nexport function generateTextFieldJSX(\n name: string,\n label: string,\n placeholder: string,\n hintJSX: string,\n requiredStar: string,\n inputType: string\n): string {\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <Input type=\"${inputType}\" placeholder=\"${placeholder}\" {...field} />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n}\n\nfunction generateFileUploadFieldJSX(\n field: FormField,\n name: string,\n label: string,\n hintJSX: string,\n requiredStar: string\n): string {\n const accept = field.accept || '*/*'\n const maxSize = field.maxFileSize || 10\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <MediaUploadField\n value={field.value}\n onChange={field.onChange}\n onBlur={field.onBlur}\n accept=\"${accept}\"\n maxSizeInMB={${maxSize}}\n label=\"\"\n />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n}\n\nfunction generateListFieldJSX(\n field: FormField,\n name: string,\n label: string,\n hintJSX: string,\n requiredStar: string\n): string {\n if (!field.fields || field.fields.length === 0) {\n return generateTextFieldJSX(name, label, field.placeholder || '', hintJSX, requiredStar, 'text')\n }\n\n const singularLabel = singularize(label)\n\n const nestedFieldsJSX = field.fields\n .map((nf) => {\n const nfLabel = escapeJsx(nf.label || nf.name || '')\n const nfPlaceholder = nf.placeholder || ''\n\n if (nf.type === 'select' && nf.options && nf.options.length > 0) {\n const selectItems = nf.options\n .map(\n (opt) =>\n ` <SelectItem value=\"${opt.value}\">${escapeJsx(opt.label)}</SelectItem>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name={\\`${name}.\\${index}.${nf.name}\\`}\n render={({ field: formField }) => (\n <FormItem className=\"flex-1\">\n <FormLabel>${nfLabel}</FormLabel>\n <Select onValueChange={formField.onChange} defaultValue={formField.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"${nf.placeholder || 'Select...'}\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n${selectItems}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n\n return ` <FormField\n control={form.control}\n name={\\`${name}.\\${index}.${nf.name}\\`}\n render={({ field: formField }) => (\n <FormItem className=\"flex-1\">\n <FormLabel>${nfLabel}</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"${nfPlaceholder}\" {...formField} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />`\n })\n .join('\\n')\n\n const defaultObj = field.fields\n .map((nf) => {\n if (nf.type === 'select' || nf.type === 'radio') return `${nf.name}: undefined`\n if (nf.type === 'checkbox') return `${nf.name}: false`\n if (nf.type === 'number') return `${nf.name}: undefined`\n return `${nf.name}: ''`\n })\n .join(', ')\n\n return ` <div className=\"space-y-2\">\n <FormLabel className=\"text-sm font-medium leading-none\">${label}${requiredStar}</FormLabel>${hintJSX}\n {${name}FieldArray.fields.map((item, index) => (\n <div key={item.id} className=\"relative rounded-lg border p-4\">\n <button\n type=\"button\"\n onClick={() => ${name}FieldArray.remove(index)}\n className=\"absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-destructive/10 hover:text-destructive\"\n >\n <Trash2 className=\"size-4\" />\n <span className=\"sr-only\">Remove</span>\n </button>\n <div className=\"space-y-4 pr-8\">\n${nestedFieldsJSX}\n </div>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => ${name}FieldArray.append({ ${defaultObj} })}\n >\n Add ${singularLabel}\n </Button>\n </div>`\n}\n","/**\n * Drizzle ORM type mappings for schema fields and form fields\n */\n\nimport type { FormField, SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const DRIZZLE_DEFAULTS = {\n VARCHAR_LENGTH: 255,\n DECIMAL_PRECISION: 10,\n DECIMAL_SCALE: 2\n} as const\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\n/**\n * Check if a field name suggests it's a URL field\n */\nfunction isUrlField(fieldName: string): boolean {\n const urlKeywords = ['url', 'link', 'href', 'website', 'avatar', 'logo', 'thumbnail']\n const lowerName = fieldName.toLowerCase()\n return urlKeywords.some((keyword) => lowerName.includes(keyword))\n}\n\n// ============================================================================\n// Schema Field → Drizzle Type (for database generator)\n// ============================================================================\n\n/**\n * Map a schema field type to Drizzle ORM column type\n * @param field - The schema field\n * @param requiredImports - Set to track which Drizzle imports are needed\n * @returns The Drizzle column type expression\n */\nexport function toDrizzleType(field: SchemaField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'serial':\n requiredImports.add('serial')\n return 'serial()'\n case 'string':\n case 'varchar':\n if (isUrlField(field.name) && !field.length) {\n requiredImports.add('text')\n return 'text()'\n }\n requiredImports.add('varchar')\n return field.length\n ? `varchar({ length: ${field.length} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'image':\n case 'video':\n case 'media':\n requiredImports.add('text')\n return 'text()'\n case 'text':\n case 'markdown':\n case 'richtext':\n requiredImports.add('text')\n return 'text()'\n case 'number':\n requiredImports.add('integer')\n return 'integer()'\n case 'decimal':\n requiredImports.add('decimal')\n if (field.precision && field.scale) {\n return `decimal({ precision: ${field.precision}, scale: ${field.scale} })`\n }\n return `decimal({ precision: ${DRIZZLE_DEFAULTS.DECIMAL_PRECISION}, scale: ${DRIZZLE_DEFAULTS.DECIMAL_SCALE} })`\n case 'boolean':\n requiredImports.add('boolean')\n return 'boolean()'\n case 'timestamp':\n requiredImports.add('timestamp')\n return \"timestamp({ precision: 3, mode: 'string' })\"\n case 'date':\n requiredImports.add('date')\n return \"date({ mode: 'string' })\"\n case 'time':\n case 'select':\n case 'icon':\n requiredImports.add('varchar')\n return field.length\n ? `varchar({ length: ${field.length} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'curriculum':\n requiredImports.add('jsonb')\n return `jsonb().$type<{ mode: 'sequential'; items: Array<{ title?: string; description?: string }> } | { mode: 'weekly'; weeks: Array<{ weekNumber: number; weekTitle?: string; weekDescription?: string; durationHours?: number; items: Array<{ title?: string; description?: string }> }> }>()`\n case 'list':\n requiredImports.add('jsonb')\n if (field.fields && field.fields.length > 0) {\n const nestedType = buildNestedListType(field.fields)\n return `jsonb().$type<Array<{ ${nestedType} }>>()`\n }\n return 'jsonb().$type<string[]>()'\n case 'relationship':\n requiredImports.add('integer')\n return 'integer()'\n default:\n requiredImports.add('text')\n return 'text()'\n }\n}\n\n/**\n * Build nested type string for list fields with nested fields\n */\nfunction buildNestedListType(fields: SchemaField[]): string {\n return fields\n .flatMap((f) => {\n let type: string\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n const innerType = f.fields\n .map((nf) => {\n let nfType: string\n if (nf.type === 'boolean') {\n nfType = 'boolean'\n } else if (nf.type === 'number' || nf.type === 'decimal') {\n nfType = 'number'\n } else {\n nfType = 'string'\n }\n return `${quotePropertyName(nf.name)}?: ${nfType}`\n })\n .join('; ')\n type = `Array<{ ${innerType} }>`\n } else if (f.type === 'list') {\n type = 'string[]'\n } else if (f.type === 'number' || f.type === 'decimal') {\n type = 'number'\n } else if (f.type === 'boolean') {\n type = 'boolean'\n } else {\n type = 'string'\n }\n const result = [`${quotePropertyName(f.name)}?: ${type}`]\n if (f.hasIcon) {\n result.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return result\n })\n .join('; ')\n}\n\n// ============================================================================\n// Form Field → Drizzle Type (for form-pipeline)\n// ============================================================================\n\n/**\n * Map a form field type to Drizzle ORM column type\n * @param field - The form field\n * @param requiredImports - Set to track which Drizzle imports are needed\n * @returns The Drizzle column type expression\n */\nexport function formFieldToDrizzleType(field: FormField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'text':\n requiredImports.add('varchar')\n return field.maxLength\n ? `varchar({ length: ${field.maxLength} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'textarea':\n requiredImports.add('text')\n return 'text()'\n case 'email':\n requiredImports.add('varchar')\n return `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'phone':\n requiredImports.add('varchar')\n return 'varchar({ length: 50 })'\n case 'number':\n requiredImports.add('integer')\n return 'integer()'\n case 'url':\n requiredImports.add('varchar')\n return 'varchar({ length: 500 })'\n case 'date':\n requiredImports.add('date')\n return \"date({ mode: 'string' })\"\n case 'select':\n case 'radio':\n case 'timezone':\n requiredImports.add('varchar')\n return `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'checkbox':\n requiredImports.add('boolean')\n return 'boolean()'\n case 'multiselect':\n requiredImports.add('jsonb')\n return 'jsonb().$type<string[]>()'\n case 'list':\n requiredImports.add('jsonb')\n if (field.fields && field.fields.length > 0) {\n return 'jsonb().$type<Record<string, unknown>[]>()'\n }\n return 'jsonb().$type<string[]>()'\n case 'file':\n case 'upload':\n requiredImports.add('text')\n return 'text()'\n default:\n requiredImports.add('text')\n return 'text()'\n }\n}\n","/**\n * Zod validation type mappings for schema fields and form fields\n */\n\nimport type { FormField, SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\n// ============================================================================\n// Schema Field → Zod Type (for form validation)\n// ============================================================================\n\n/**\n * Map a schema field type to Zod validation schema\n * @param field - The schema field\n * @returns The Zod schema expression as a string\n */\nexport function toZodType(field: SchemaField): string {\n const label = field.label || field.name\n\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return field.required\n ? `z.number({ message: '${label} is required' })`\n : 'z.number().optional()'\n case 'boolean':\n return 'z.boolean()'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext': {\n if (field.name.toLowerCase().includes('email')) {\n const base = field.required\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().email('Please enter a valid email address').optional()`\n return field.length ? `${base}.max(${field.length})` : base\n }\n const base = field.required ? `z.string().min(1, '${label} is required')` : 'z.string()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'date':\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n return `z.string().min(1, '${label} is required')`\n case 'timestamp':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'image':\n case 'video':\n case 'media': {\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const mediaType =\n field.type === 'image' ? 'an image' : field.type === 'video' ? 'a video' : 'media'\n const base = `z.string().min(1, 'Please upload ${mediaType} for ${label}').url('Please provide a valid ${field.type} URL')`\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'list':\n return buildZodListType(field, label)\n case 'select': {\n if (field.options && field.options.length > 0) {\n const values = field.options.map((opt) => `'${opt.value}'`).join(', ')\n const valuesArray = `[${values}] as const`\n return field.required\n ? `z.string().min(1, '${label} is required').refine((val) => (${valuesArray} as readonly string[]).includes(val), { message: 'Invalid ${label}' })`\n : `z.string().refine((val) => !val || (${valuesArray} as readonly string[]).includes(val), { message: 'Invalid ${label}' }).optional()`\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'icon':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'relationship': {\n if (field.multiple) {\n return field.required\n ? `z.array(z.number()).min(1, '${label} is required')`\n : 'z.array(z.number()).optional()'\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'curriculum':\n return `z.object({\n mode: z.enum(['sequential', 'weekly']),\n items: z.array(z.object({\n title: z.string().max(255).optional(),\n description: z.string().max(500).optional()\n })).max(50),\n weeks: z.array(z.object({\n weekNumber: z.number().int().positive(),\n weekTitle: z.string().max(100).optional(),\n weekDescription: z.string().max(1000).optional(),\n durationHours: z.number().positive().optional(),\n items: z.array(z.object({\n title: z.string().max(255).optional(),\n description: z.string().max(500).optional()\n })).max(20)\n })).max(20)\n }).optional()`\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Build Zod type for list fields\n */\nfunction buildZodListType(field: SchemaField, label: string): string {\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .flatMap((nestedField) => {\n const defs: string[] = []\n const nestedZodType = toZodType(nestedField)\n const alreadyOptional = nestedZodType.includes('.optional()')\n let nestedDef = ` ${quotePropertyName(nestedField.name)}: ${nestedZodType}`\n if (!nestedField.required && !alreadyOptional) {\n nestedDef += '.optional()'\n }\n defs.push(nestedDef)\n if (nestedField.hasIcon) {\n defs.push(` ${quotePropertyName(`${nestedField.name}Icon`)}: z.string().optional()`)\n }\n return defs\n })\n .join(',\\n')\n const objectSchema = `z.object({\\n${nestedFields}\\n })`\n const arraySchema = field.maxItems\n ? `z.array(${objectSchema}).max(${field.maxItems}, '${label} cannot exceed ${field.maxItems} items')`\n : `z.array(${objectSchema})`\n return field.required\n ? `${arraySchema}.min(1, '${label} must have at least one item')`\n : `${arraySchema}.optional()`\n }\n if (field.items?.type === 'string' || field.items?.type === 'varchar') {\n const itemSchema = field.items.length ? `z.string().max(${field.items.length})` : 'z.string()'\n const arraySchema = field.maxItems\n ? `z.array(${itemSchema}).max(${field.maxItems}, '${label} cannot exceed ${field.maxItems} items')`\n : `z.array(${itemSchema})`\n return field.required\n ? `${arraySchema}.min(1, '${label} must have at least one item')`\n : `${arraySchema}.optional()`\n }\n return field.required\n ? `z.array(z.string()).min(1, '${label} must have at least one item')`\n : 'z.array(z.string()).optional()'\n}\n\n// ============================================================================\n// Form Field → Zod Type (for form-pipeline)\n// ============================================================================\n\nexport interface FormFieldZodOptions {\n treatAsOptional?: boolean\n}\n\n/**\n * Map a form field type to Zod validation schema\n * @param field - The form field\n * @param options - Options for generating the zod type\n * @returns The Zod schema expression as a string\n */\nexport function formFieldToZodType(field: FormField, options: FormFieldZodOptions = {}): string {\n const label = field.label\n const isRequired = field.required && !options.treatAsOptional\n\n switch (field.type) {\n case 'text': {\n let zodType = isRequired ? `z.string().min(1, '${label} is required')` : 'z.string()'\n if (field.minLength) {\n zodType += `.min(${field.minLength}, '${label} must be at least ${field.minLength} characters')`\n }\n if (field.maxLength) {\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n }\n if (field.pattern) {\n zodType += `.regex(new RegExp('${field.pattern}'), 'Invalid ${label} format')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'textarea': {\n let zodType = isRequired ? `z.string().min(1, '${label} is required')` : 'z.string()'\n if (field.minLength) {\n zodType += `.min(${field.minLength}, '${label} must be at least ${field.minLength} characters')`\n }\n if (field.maxLength) {\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'email':\n return isRequired\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || z.string().email().safeParse(val).success, { message: 'Please enter a valid email address' })`\n case 'phone': {\n const pattern =\n field.pattern || '^[+]?[(]?[0-9]{1,4}[)]?[-\\\\s\\\\.]?[(]?[0-9]{1,4}[)]?[-\\\\s\\\\.]?[0-9]{1,9}$'\n return isRequired\n ? `z.string().min(1, '${label} is required').regex(new RegExp('${pattern}'), 'Please enter a valid phone number')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || new RegExp('${pattern}').test(val), { message: 'Please enter a valid phone number' })`\n }\n case 'number': {\n let zodType = isRequired ? `z.number({ message: '${label} is required' })` : 'z.number()'\n if (field.min !== undefined) {\n zodType += `.min(${field.min}, '${label} must be at least ${field.min}')`\n }\n if (field.max !== undefined) {\n zodType += `.max(${field.max}, '${label} must be at most ${field.max}')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'url':\n return isRequired\n ? `z.string().min(1, '${label} is required').url('Please enter a valid URL')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || z.string().url().safeParse(val).success, { message: 'Please enter a valid URL' })`\n case 'date':\n return isRequired\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n case 'select':\n case 'radio':\n if (field.options && field.options.length > 0) {\n const values = field.options.map((opt) => `'${opt.value}'`).join(', ')\n return isRequired\n ? `z.enum([${values}], { message: '${label} is required' })`\n : `z.enum([${values}]).optional()`\n }\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'checkbox':\n return isRequired\n ? `z.boolean().refine(val => val === true, { message: '${label} is required' })`\n : 'z.boolean().optional()'\n case 'multiselect':\n return isRequired\n ? `z.array(z.string()).min(1, '${label} is required')`\n : 'z.array(z.string()).optional()'\n case 'timezone':\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((f) => `${f.name}: ${formFieldToZodType(f, options)}`)\n .join(', ')\n return isRequired\n ? `z.array(z.object({ ${nestedFields} })).min(1, '${label} is required')`\n : `z.array(z.object({ ${nestedFields} })).optional()`\n }\n return isRequired\n ? `z.array(z.string()).min(1, '${label} is required')`\n : 'z.array(z.string()).optional()'\n case 'file':\n case 'upload':\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n default:\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n","/**\n * TypeScript, form field, and SQL type mappings for schema fields\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize, quotePropertyName } from '../../utils/string.js'\nimport { DRIZZLE_DEFAULTS } from './drizzle.js'\n\n// ============================================================================\n// Schema Field → TypeScript Type (for actions generator)\n// ============================================================================\n\n/**\n * Map a schema field type to TypeScript type\n * @param field - The schema field\n * @param mode - 'input' for form input types, 'output' for database output types\n * @returns The TypeScript type as a string\n */\nexport function toTypeScriptType(field: SchemaField, mode: 'input' | 'output' = 'output'): string {\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return 'number'\n case 'boolean':\n return 'boolean'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext':\n case 'date':\n case 'time':\n case 'timestamp':\n case 'image':\n case 'video':\n case 'media':\n case 'icon':\n case 'select':\n return 'string'\n case 'relationship':\n if (mode === 'input') {\n return field.multiple ? 'number[]' : 'string'\n }\n if (field.relationship) {\n const relationshipSingular = singularize(field.relationship)\n const relationshipPascal = toPascalCase(relationshipSingular)\n return field.multiple ? `${relationshipPascal}Data[]` : `${relationshipPascal}Data | null`\n }\n return 'string'\n case 'group':\n if (field.fields && field.fields.length > 0) {\n const groupType = field.fields\n .map((f) => {\n const type = toTypeScriptType(f, mode)\n return `${quotePropertyName(f.name)}?: ${type}`\n })\n .join('; ')\n return `{ ${groupType} }`\n }\n return 'Record<string, unknown>'\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .flatMap((f) => {\n const type = toTypeScriptType(f, 'input')\n const fields = [`${quotePropertyName(f.name)}?: ${type}`]\n if (f.hasIcon) {\n fields.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return fields\n })\n .join('; ')\n return `Array<{ ${nestedType} }>`\n }\n return 'string[]'\n case 'curriculum':\n return '{ mode: \"sequential\" | \"weekly\"; items: Array<{ title?: string; description?: string }>; weeks: Array<{ weekNumber: number; weekTitle?: string; weekDescription?: string; durationHours?: number; items: Array<{ title?: string; description?: string }> }> }'\n default:\n return 'string'\n }\n}\n\n// ============================================================================\n// Schema Field → Form Field Type (for form generator)\n// ============================================================================\n\n/**\n * Map a schema field type to HTML form input type\n * @param field - The schema field\n * @returns The form input type (checkbox, textarea, number, date, etc.)\n */\nexport function toFormFieldType(field: SchemaField): string {\n switch (field.type) {\n case 'boolean':\n return 'checkbox'\n case 'text':\n return 'textarea'\n case 'markdown':\n return 'markdown'\n case 'richtext':\n return 'richtext'\n case 'number':\n case 'decimal':\n return 'number'\n case 'date':\n return 'date'\n case 'time':\n return 'time'\n case 'timestamp':\n return 'datetime-local'\n default:\n return 'text'\n }\n}\n\n// ============================================================================\n// Schema Field → SQL Type (for raw SQL migrations)\n// ============================================================================\n\n/**\n * Map a schema field type to SQL column type\n * @param field - The schema field\n * @returns The SQL column type\n */\nexport function toSQLType(field: SchemaField): string {\n switch (field.type) {\n case 'serial':\n return 'SERIAL'\n case 'string':\n case 'varchar':\n return field.length\n ? `VARCHAR(${field.length})`\n : `VARCHAR(${DRIZZLE_DEFAULTS.VARCHAR_LENGTH})`\n case 'text':\n case 'markdown':\n case 'richtext':\n case 'image':\n case 'video':\n case 'media':\n return 'TEXT'\n case 'number':\n return 'INTEGER'\n case 'decimal':\n return `DECIMAL(${field.precision || DRIZZLE_DEFAULTS.DECIMAL_PRECISION}, ${field.scale || DRIZZLE_DEFAULTS.DECIMAL_SCALE})`\n case 'boolean':\n return 'BOOLEAN'\n case 'timestamp':\n return 'TIMESTAMP(3)'\n case 'date':\n return 'DATE'\n case 'time':\n case 'select':\n case 'icon':\n return `VARCHAR(${DRIZZLE_DEFAULTS.VARCHAR_LENGTH})`\n case 'list':\n case 'curriculum':\n return 'JSONB'\n case 'relationship':\n return 'INTEGER'\n default:\n return 'TEXT'\n }\n}\n","/**\n * Single-step (flat) form component generator\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toKebabCase } from '../../utils/string.js'\nimport {\n type StepResult,\n resolveUiImport,\n escapeJsx,\n renderFieldsJSX,\n buildZodFields,\n buildDefaultValues,\n buildFieldArrayDecls,\n buildWatchDecls,\n getListFields,\n} from './form-component-shared.js'\n\nexport function generateSingleStepForm(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const kebab = toKebabCase(formName)\n const filePath = path.join(cwd, cmsDir, 'components', 'forms', `${kebab}-form.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const zodFields = buildZodFields(fields)\n const defaults = buildDefaultValues(fields)\n const listFields = getListFields(fields)\n const hasListFields = listFields.length > 0\n const { setup: watchSetup } = buildWatchDecls(fields)\n\n const rawFields = schema.fields || []\n const fieldJSX = renderFieldsJSX(rawFields)\n\n const submitText = schema.submitButtonText || 'Submit'\n const successMessage = escapeJsx(schema.successMessage || 'Form submitted successfully!')\n\n const rhfImport = hasListFields\n ? `import { useFieldArray, useForm } from 'react-hook-form'`\n : `import { useForm } from 'react-hook-form'`\n\n const fieldArraySetup = hasListFields ? `\\n${buildFieldArrayDecls(listFields)}\\n` : ''\n\n const hasRadio = fields.some((f) => f.type === 'radio')\n const hasFileUpload = fields.some((f) => f.type === 'file' || f.type === 'upload')\n const buttonImport = resolveUiImport(cwd, 'button')\n const formImport = resolveUiImport(cwd, 'form')\n const inputImport = resolveUiImport(cwd, 'input')\n const textareaImport = resolveUiImport(cwd, 'textarea')\n const selectImport = resolveUiImport(cwd, 'select')\n const radioGroupImport = resolveUiImport(cwd, 'radio-group')\n const mediaUploadImport = resolveUiImport(cwd, 'media-upload-field')\n\n const queryClientImport = hasFileUpload\n ? `\\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'`\n : ''\n const queryClientSetup = hasFileUpload\n ? `\\nconst queryClient = new QueryClient()\\n`\n : ''\n\n const formComponentDecl = hasFileUpload ? `function ${pascal}FormInner` : `export function ${pascal}Form`\n const exportWrapper = hasFileUpload\n ? `\\nexport function ${pascal}Form() {\n return (\n <QueryClientProvider client={queryClient}>\n <${pascal}FormInner />\n </QueryClientProvider>\n )\n}\\n`\n : ''\n\n const lucideImport = hasListFields ? `\\nimport { Trash2 } from 'lucide-react'` : ''\n\n const content = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'${lucideImport}\nimport { useState } from 'react'\n${rhfImport}\nimport { z } from 'zod/v3'${queryClientImport}\nimport { create${pascal}Submission } from '@cms/actions/${kebab}-form'\nimport { Button } from '${buttonImport}'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '${formImport}'\nimport { Input } from '${inputImport}'${hasFileUpload ? `\\nimport { MediaUploadField } from '${mediaUploadImport}'` : ''}${hasRadio ? `\\nimport { RadioGroup, RadioGroupItem } from '${radioGroupImport}'` : ''}\nimport { Textarea } from '${textareaImport}'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '${selectImport}'\n\nconst formSchema = z.object({\n${zodFields}\n})\n\ntype FormValues = z.infer<typeof formSchema>\n${queryClientSetup}\n${formComponentDecl}() {\n const [submitted, setSubmitted] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaults}\n },\n })\n${fieldArraySetup}${watchSetup}\n async function onSubmit(values: FormValues) {\n setSubmitting(true)\n try {\n const result = await create${pascal}Submission(values)\n if (result.success) {\n setSubmitted(true)\n } else {\n form.setError('root', { message: result.error || 'Something went wrong' })\n }\n } catch {\n form.setError('root', { message: 'Something went wrong. Please try again.' })\n } finally {\n setSubmitting(false)\n }\n }\n\n if (submitted) {\n return (\n <div className=\"rounded-lg border p-6 text-center\">\n <h3 className=\"text-lg font-semibold\">Thank you!</h3>\n <p className=\"mt-2 text-muted-foreground\">${successMessage}</p>\n </div>\n )\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n${fieldJSX}\n\n {form.formState.errors.root && (\n <p className=\"text-sm text-destructive\">{form.formState.errors.root.message}</p>\n )}\n\n <Button type=\"submit\" disabled={submitting}>\n {submitting ? 'Submitting...' : '${submitText}'}\n </Button>\n </form>\n </Form>\n )\n}\n${exportWrapper}`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Form pipeline step 4: Public form component generation\n * Routes to single-step or multi-step generator based on schema structure.\n */\n\nimport { isMultiStepForm } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport type { StepResult } from './form-component-shared.js'\nimport { generateMultiStepForm } from './form-component-multistep.js'\nimport { generateSingleStepForm } from './form-component-single.js'\n\nexport function generateFormComponent(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n if (isMultiStepForm(schema) && schema.steps!.length > 1) {\n return generateMultiStepForm(schema, cwd, cmsDir, options)\n }\n return generateSingleStepForm(schema, cwd, cmsDir, options)\n}\n","/**\n * Form pipeline step 1: Database schema generation for form submissions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields, hasDynamicFields } from '../../core/field-helpers/index.js'\nimport { formFieldToDrizzleType } from '../../core/type-mappers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase } from '../../utils/string.js'\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n // Skip optional semicolon and trailing whitespace\n let end = i + 1\n while (end < content.length && (content[end] === ';' || content[end] === ' ' || content[end] === '\\t')) {\n end++\n }\n if (end < content.length && content[end] === '\\n') {\n end++\n }\n return end\n }\n }\n\n return content.length\n}\n\ninterface StepResult {\n files: string[]\n}\n\nexport function generateFormDatabase(\n schema: FormSchema,\n cwd: string,\n dbSchemaPath: string,\n options: GeneratorOptions\n): StepResult {\n const tableName = `${toCamelCase(schema.name)}Submissions`\n const fields = getAllFormSchemaFields(schema)\n const includeDynamic = hasDynamicFields(schema)\n\n const requiredImports = new Set<string>(['serial', 'timestamp', 'text'])\n if (includeDynamic) requiredImports.add('jsonb')\n\n // Generate field definitions\n const fieldDefs = fields\n .map((field) => {\n const drizzleType = formFieldToDrizzleType(field, requiredImports)\n return ` ${field.name}: ${drizzleType},`\n })\n .join('\\n')\n\n const customFieldsCol = includeDynamic\n ? '\\n customFields: jsonb().$type<Record<string, unknown>>(),'\n : ''\n\n const tableSchema = `\nexport const ${tableName} = pgTable('${toPascalCase(schema.name)}Submissions', {\n id: serial().primaryKey().notNull(),\n${fieldDefs}${customFieldsCol}\n ipAddress: text(),\n userAgent: text(),\n submittedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull(),\n createdAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull(),\n updatedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()\n})\n`\n\n const filePath = path.join(cwd, dbSchemaPath)\n let content = fs.readFileSync(filePath, 'utf-8')\n\n // Merge imports\n const pgCoreMatch = content.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/)\n if (pgCoreMatch) {\n const existing = new Set(\n pgCoreMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n )\n const merged = Array.from(new Set([...existing, ...requiredImports])).sort()\n content = content.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n `import {\\n ${merged.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n )\n }\n\n // Ensure sql import\n if (!content.includes('import { sql }')) {\n content = content.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n (match) => `import { sql } from 'drizzle-orm'\\n${match}`\n )\n }\n\n // Remove all existing table definitions if --force (handles prior duplicates)\n if (content.includes(`export const ${tableName}`)) {\n if (!options.force) {\n return { files: [dbSchemaPath] }\n }\n const marker = `export const ${tableName} =`\n let start = content.indexOf(marker)\n while (start !== -1) {\n const end = findTableEnd(content, start)\n const actualStart = start > 0 && content[start - 1] === '\\n' ? start - 1 : start\n content = content.slice(0, actualStart) + content.slice(end)\n start = content.indexOf(marker)\n }\n }\n\n content += `\\n${tableSchema}`\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return { files: [dbSchemaPath] }\n}\n","/**\n * Form pipeline step 3: React Query hook for form submissions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\n\ninterface StepResult {\n files: string[]\n}\n\nexport function generateFormHook(\n schema: FormSchema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const camel = toCamelCase(formName)\n const kebab = toKebabCase(formName)\n\n const filePath = path.join(cwd, hooksDir, `use-${kebab}-form.ts`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const successMsg = (schema.successMessage || 'Form submitted successfully').replace(/'/g, \"\\\\'\")\n\n const content = `import {\n create${pascal}Submission,\n delete${pascal}Submission,\n export${pascal}SubmissionsCSV,\n export${pascal}SubmissionsJSON,\n get${pascal}Submission,\n get${pascal}Submissions,\n} from '@cms/actions/${kebab}-form'\nimport type { Create${pascal}SubmissionInput } from '@cms/actions/${kebab}-form'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { toast } from 'sonner'\n\nexport function use${pascal}Submissions(search?: string) {\n return useQuery({\n queryKey: ['${camel}-submissions', search ?? ''],\n queryFn: () => get${pascal}Submissions()\n })\n}\n\nexport function use${pascal}Submission(id: number | null) {\n return useQuery({\n queryKey: ['${camel}-submission', id],\n queryFn: () => get${pascal}Submission(id!),\n enabled: !!id\n })\n}\n\nexport function useCreate${pascal}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (data: Create${pascal}SubmissionInput) => create${pascal}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${successMsg}')\n await queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n } else {\n toast.error(result.error || 'Failed to submit form')\n }\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to submit form')\n }\n })\n}\n\nexport function useDelete${pascal}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: number) => delete${pascal}Submission(id),\n onSuccess: async () => {\n toast.success('Submission deleted successfully')\n await queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to delete submission')\n }\n })\n}\n\nexport function useExport${pascal}SubmissionsCSV() {\n return useMutation({\n mutationFn: export${pascal}SubmissionsCSV,\n onSuccess: (csvContent) => {\n const blob = new Blob([csvContent], { type: 'text/csv' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = '${formName}-submissions-' + new Date().toISOString().split('T')[0] + '.csv'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n window.URL.revokeObjectURL(url)\n toast.success('CSV exported successfully')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to export CSV')\n }\n })\n}\n\nexport function useExport${pascal}SubmissionsJSON() {\n return useMutation({\n mutationFn: export${pascal}SubmissionsJSON,\n onSuccess: (jsonContent) => {\n const blob = new Blob([jsonContent], { type: 'application/json' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = '${formName}-submissions-' + new Date().toISOString().split('T')[0] + '.json'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n window.URL.revokeObjectURL(url)\n toast.success('JSON exported successfully')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to export JSON')\n }\n })\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Form pipeline orchestrator — runs all form generation steps in sequence\n */\n\nimport type { BetterstartConfig } from '../../config/types.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { generateEmailTemplate } from '../email-template.js'\nimport { generateFormAdminPages } from '../form-admin/index.js'\nimport { updateFormNavigation } from '../form-navigation.js'\nimport { generateFormActions } from './form-actions.js'\nimport { generateFormComponent } from './form-component.js'\nimport { generateFormDatabase } from './form-database.js'\nimport { generateFormHook } from './form-hook.js'\n\nexport interface FormPipelineResult {\n success: boolean\n files: string[]\n errors: string[]\n}\n\n/**\n * Resolve output paths from config for form generation\n */\nfunction resolveFormPaths(config: BetterstartConfig) {\n const cms = config.paths?.cms ?? './cms'\n const pages = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n return {\n cmsDir: cms,\n pagesDir: pages,\n dbSchemaPath: `${cms}/db/schema.ts`,\n actionsDir: `${cms}/lib/actions`,\n hooksDir: `${cms}/hooks`\n }\n}\n\n/**\n * Run the form generation pipeline\n */\nexport function runFormPipeline(\n schema: FormSchema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): FormPipelineResult {\n const paths = resolveFormPaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema (submissions)',\n run: () => generateFormDatabase(schema, cwd, paths.dbSchemaPath, options).files\n },\n {\n name: 'Server actions',\n run: () => generateFormActions(schema, cwd, paths.actionsDir, options).files\n },\n {\n name: 'React Query hook',\n run: () => generateFormHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Public form component',\n run: () => generateFormComponent(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Admin pages',\n run: () => generateFormAdminPages(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Navigation',\n run: () => updateFormNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Email template',\n run: () => generateEmailTemplate(schema, cwd, paths.cmsDir, options).files\n }\n ]\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return { success: errors.length === 0, files, errors }\n}\n","/**\n * Generator 2: Server actions — cms/lib/actions/<name>/\n * Generates 'use server' CRUD actions for an entity schema,\n * split into individual files with a barrel index.ts.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields, getManyToManyFields } from '../../core/field-helpers/index.js'\nimport type { Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toKebabCase, quotePropertyName } from '../../utils/string.js'\nimport type { ActionsGeneratorResult } from './action-helpers.js'\nimport {\n generateFieldMapping,\n getFieldType,\n buildRelationshipSelect,\n buildResultMapping,\n buildSingleRowMapping,\n buildExplicitSelect,\n findListFieldsWithRelationships,\n generatePopulateListRelsFunction\n} from './action-helpers.js'\nimport type { EntityCtx } from './entity-file-contents.js'\nimport {\n genTypesContent,\n genHelpersContent,\n genGetPluralContent,\n genGetByIdContent,\n genGetBySlugContent,\n genCreateContent,\n genUpdateContent,\n genDeleteContent,\n genDeleteBulkContent,\n genSortOrderContent,\n genBulkSortOrderContent,\n genM2MFiles,\n genDistinctFiles,\n genBarrelContent\n} from './entity-file-contents.js'\n\n/**\n * Generate server action files for an entity, split into individual files.\n */\nexport function generateActions(\n schema: Schema,\n cwd: string,\n actionsDir: string,\n options: { force?: boolean; schemasDir?: string } = {}\n): ActionsGeneratorResult {\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, schema.name)\n const oldFilePath = path.join(absActionsDir, `${schema.name}.ts`)\n\n // Check existence: both old single-file format and new directory format\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n // Force: clean up old file and stale directory\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n const ctx = buildEntityContext(schema)\n\n // Build all file entries\n const kebabSingular = toKebabCase(ctx.singular)\n const kebabPlural = toKebabCase(ctx.plural)\n const files: Array<{ name: string; content: string }> = []\n\n files.push({ name: 'types.ts', content: genTypesContent(ctx) })\n\n const helpersContent = genHelpersContent(ctx)\n if (helpersContent) {\n files.push({ name: 'helpers.ts', content: helpersContent })\n }\n\n files.push({ name: `get-${kebabPlural}.ts`, content: genGetPluralContent(ctx) })\n files.push({ name: `get-${kebabSingular}-by-id.ts`, content: genGetByIdContent(ctx) })\n\n const bySlugContent = genGetBySlugContent(ctx)\n if (bySlugContent) {\n files.push({ name: `get-${kebabSingular}-by-slug.ts`, content: bySlugContent })\n }\n\n files.push({ name: `create-${kebabSingular}.ts`, content: genCreateContent(ctx) })\n files.push({ name: `update-${kebabSingular}.ts`, content: genUpdateContent(ctx) })\n files.push({ name: `delete-${kebabSingular}.ts`, content: genDeleteContent(ctx) })\n files.push({ name: `delete-bulk-${kebabPlural}.ts`, content: genDeleteBulkContent(ctx) })\n files.push({ name: `update-${kebabSingular}-sort-order.ts`, content: genSortOrderContent(ctx) })\n files.push({ name: `bulk-update-${kebabPlural}-sort-order.ts`, content: genBulkSortOrderContent(ctx) })\n\n // M2M files (conditional, per relationship)\n files.push(...genM2MFiles(ctx))\n\n // Distinct filter files (conditional, per filter field)\n files.push(...genDistinctFiles(ctx))\n\n // Barrel index.ts (must be last, references other files)\n files.push({ name: 'index.ts', content: genBarrelContent(files, ctx) })\n\n // Write all files\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.join(actionsDir, schema.name, f.name)) }\n}\n\n// ============================================================================\n// Context builder — computes all shared state for content generators\n// ============================================================================\n\nfunction buildEntityContext(schema: Schema): EntityCtx {\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const tableVar = toCamelCase(schema.name)\n const camelPlural = toCamelCase(plural)\n const camelSingular = toCamelCase(singular)\n\n const dbFields = flattenFields(schema.fields).filter((f) => !isLayoutField(f.type))\n const m2mFields = getManyToManyFields(schema.fields)\n const hasM2M = m2mFields.length > 0\n\n const relationshipFields = dbFields.filter(\n (f) => f.type === 'relationship' && f.relationship && !f.multiple\n )\n const hasRelationships = relationshipFields.length > 0\n\n const regularDbFields = dbFields.filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n const listFieldsWithRels = findListFieldsWithRelationships(dbFields)\n const hasListRels = listFieldsWithRels.length > 0\n\n const allListRelQueries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n listFieldName: string\n }> = []\n\n for (const { field: listField, path: fieldPath } of listFieldsWithRels) {\n const rels = (listField.fields || []).filter((f) => f.type === 'relationship' && f.relationship)\n for (const relField of rels) {\n allListRelQueries.push({\n fieldPath: fieldPath.join('_'),\n relField,\n relTable: toCamelCase(relField.relationship!),\n listFieldName: listField.name\n })\n }\n }\n\n const populateListRelsFn = hasListRels\n ? generatePopulateListRelsFunction(allListRelQueries, Singular)\n : ''\n\n const htmlOutputFields = regularDbFields.filter(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n const hasHtmlOutput = htmlOutputFields.length > 0\n\n const hasSlug = regularDbFields.some((f) => f.name === 'slug')\n const hasDraft = schema.actions?.draft === true\n const hasPublished = regularDbFields.some((f) => f.name === 'published')\n const hasSearch = (schema.search?.fields || []).length > 0\n const searchFields = schema.search?.fields || []\n const hasFilters = (schema.filters || []).length > 0\n const hasAutoSlug = schema.autoSlugify?.enabled === true\n\n // Build allDbFields (with auto-added fields)\n const allDbFields = [...regularDbFields]\n if (hasDraft && !hasPublished) {\n allDbFields.push({ name: 'published', type: 'boolean' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'createdAt')) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'updatedAt')) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'sortOrder')) {\n allDbFields.push({ name: 'sortOrder', type: 'number' as const, required: true })\n }\n\n const listExcludeFields = new Set(htmlOutputFields.map((f) => f.name))\n const listDbFields = hasHtmlOutput\n ? allDbFields.filter((f) => !listExcludeFields.has(f.name))\n : allDbFields\n\n const createFields = regularDbFields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'sortOrder'\n )\n\n const filterableFields = allDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'sortOrder' &&\n ['string', 'varchar', 'text', 'boolean', 'number', 'decimal'].includes(f.type)\n )\n\n // Per-file DB imports\n const relTableImports = relationshipFields.map((f) => toCamelCase(f.relationship!))\n const listRelTableImports = allListRelQueries.map((q) => q.relTable)\n\n // --- Build interfaces ---\n const dataFields = allDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const m2mFieldTypes = m2mFields.map((f) => ` ${quotePropertyName(f.name)}: number[]`).join('\\n')\n const htmlFieldTypes = htmlOutputFields.map((f) => ` ${f.name}Html: string`).join('\\n')\n\n const dataInterface = `export interface ${Singular}Data {\\n${dataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\\n}`\n\n const displayDbFields = allDbFields.filter((f) => !htmlOutputFields.some((h) => h.name === f.name))\n const displayDataFields = displayDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const displayDataInterface = hasHtmlOutput\n ? `export interface ${Singular}DisplayData {\\n${displayDataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\\n}`\n : ''\n\n const responseInterface = `export interface ${Plural}Response {\\n ${camelPlural}: ${Singular}Data[]\\n total: number\\n}`\n\n const filtersInterfaceFields = filterableFields\n .map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f)}`)\n .join('\\n')\n const filtersInterface = `export interface Get${Plural}Filters {\\n search?: string\\n${filtersInterfaceFields}\\n limit?: number\\n}`\n\n const createInterfaceFields = createFields\n .map(\n (f) => ` ${quotePropertyName(f.name)}${f.required ? '' : '?'}: ${getFieldType(f, 'input')}`\n )\n .join('\\n')\n const createInterface = `export interface Create${Singular}Input {\\n${createInterfaceFields}${hasDraft ? `\\n published?: boolean` : ''}\\n}`\n\n const updateInterfaceFields = createFields\n .map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`)\n .join('\\n')\n const updateInterface = `export interface Update${Singular}Input {\\n id: number\\n${updateInterfaceFields}${hasDraft ? `\\n published?: boolean` : ''}\\n}`\n\n // --- Build select clauses ---\n const selectClause = hasRelationships\n ? buildRelationshipSelect(allDbFields, relationshipFields, tableVar)\n : `db.select().from(${tableVar})`\n\n const listSelectClause = hasHtmlOutput\n ? hasRelationships\n ? buildRelationshipSelect(listDbFields, relationshipFields, tableVar)\n : buildExplicitSelect(listDbFields, tableVar)\n : selectClause\n\n const displaySelectClause =\n hasHtmlOutput && hasSlug\n ? hasRelationships\n ? buildRelationshipSelect(displayDbFields, relationshipFields, tableVar, htmlOutputFields)\n : buildExplicitSelect(displayDbFields, tableVar, htmlOutputFields)\n : selectClause\n\n // --- Build query parts ---\n const filterConditions = filterableFields\n .map((f) =>\n f.type === 'boolean'\n ? ` if (filters?.${f.name} !== undefined) {\\n conditions.push(eq(${tableVar}.${f.name}, filters.${f.name}))\\n }`\n : ` if (filters?.${f.name}) {\\n conditions.push(eq(${tableVar}.${f.name}, filters.${f.name}))\\n }`\n )\n .join('\\n')\n\n const searchBlock = hasSearch\n ? ` const search = filters?.search\\n if (search && typeof search === 'string' && search.trim()) {\\n const searchTerm = \\`%\\${search.trim().toLowerCase()}%\\`\\n conditions.push(\\n or(\\n${searchFields.map((f) => ` ilike(${tableVar}.${f}, searchTerm)`).join(',\\n')}\\n )\\n )\\n }\\n`\n : ''\n\n const resultMapping = hasRelationships\n ? buildResultMapping(allDbFields, relationshipFields, Plural, camelPlural, Singular, hasListRels)\n : hasListRels\n ? `\\n\\n const populated${Plural} = await Promise.all(\\n results.map(record => populate${Singular}ListRelationships(record as ${Singular}Data))\\n )\\n\\n return {\\n ${camelPlural}: populated${Plural},\\n total: populated${Plural}.length\\n }`\n : `\\n return {\\n ${camelPlural}: results as ${Singular}Data[],\\n total: results.length\\n }`\n\n const listResultMapping =\n hasHtmlOutput && hasRelationships\n ? buildResultMapping(\n listDbFields,\n relationshipFields,\n Plural,\n camelPlural,\n Singular,\n hasListRels\n )\n : resultMapping\n\n const fieldMeta = createFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const createMappings = createFields\n .map((f) => ` ${f.name}: ${generateFieldMapping(f)}`)\n .join(',\\n')\n\n const htmlCreateBlock = hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n htmlOutputFields\n .map((f) => ` const ${f.name}Html = renderMarkdownSync(input.${f.name} || '')`)\n .join('\\n') +\n '\\n'\n : ''\n\n const htmlCreateMappings = htmlOutputFields.map((f) => ` ${f.name}Html`).join(',\\n')\n\n const autoSlugCreate = hasAutoSlug\n ? `\\n if ((!input.${schema.autoSlugify!.targetField} || input.${schema.autoSlugify!.targetField} === '') && input.${schema.autoSlugify!.sourceField}) {\\n input.${schema.autoSlugify!.targetField} = slugify(input.${schema.autoSlugify!.sourceField})\\n }\\n`\n : ''\n const autoSlugUpdate = hasAutoSlug\n ? `\\n if (updateData.${schema.autoSlugify!.sourceField}) {\\n if (updateData.${schema.autoSlugify!.targetField} === '' || updateData.${schema.autoSlugify!.targetField} === undefined) {\\n updateData.${schema.autoSlugify!.targetField} = slugify(updateData.${schema.autoSlugify!.sourceField})\\n }\\n }\\n`\n : ''\n\n const cacheTag = `${plural}:all`\n\n // --- Build single row returns ---\n const singleRowReturn = (() => {\n if (hasRelationships && hasListRels) {\n return `const row = result[0]\\n return await populate${Singular}ListRelationships(${buildSingleRowMapping(allDbFields, relationshipFields, `${Singular}Data`)})`\n }\n if (hasRelationships) {\n return `const row = result[0]\\n return ${buildSingleRowMapping(allDbFields, relationshipFields, `${Singular}Data`)}`\n }\n if (hasListRels) {\n return `return await populate${Singular}ListRelationships(result[0] as ${Singular}Data)`\n }\n return `return result[0] as ${Singular}Data`\n })()\n\n const displaySingleRowReturn = hasHtmlOutput\n ? (() => {\n const displayType = `${Singular}DisplayData`\n if (hasRelationships && hasListRels) {\n return `const row = result[0]\\n return await populate${Singular}ListRelationships(${buildSingleRowMapping(displayDbFields, relationshipFields, `${Singular}Data`, htmlOutputFields)}) as unknown as ${displayType}`\n }\n if (hasRelationships) {\n return `const row = result[0]\\n return ${buildSingleRowMapping(displayDbFields, relationshipFields, displayType, htmlOutputFields)}`\n }\n if (hasListRels) {\n return `return await populate${Singular}ListRelationships(result[0] as unknown as ${Singular}Data) as unknown as ${displayType}`\n }\n return `return result[0] as ${displayType}`\n })()\n : singleRowReturn\n\n return {\n singular,\n plural,\n Singular,\n Plural,\n tableVar,\n camelSingular,\n camelPlural,\n cacheTag,\n hasRelationships,\n hasM2M,\n hasListRels,\n hasHtmlOutput,\n hasSlug,\n hasDraft,\n hasSearch,\n hasFilters,\n hasAutoSlug,\n searchFields,\n htmlOutputFields,\n m2mFields,\n filterableFields,\n relTableImports,\n listRelTableImports,\n dataInterface,\n displayDataInterface,\n responseInterface,\n filtersInterface,\n createInterface,\n updateInterface,\n selectClause,\n listSelectClause,\n displaySelectClause,\n filterConditions,\n searchBlock,\n resultMapping,\n listResultMapping,\n singleRowReturn,\n displaySingleRowReturn,\n fieldMeta,\n createMappings,\n htmlCreateBlock,\n htmlCreateMappings,\n autoSlugCreate,\n autoSlugUpdate,\n populateListRelsFn,\n filters: schema.filters || []\n }\n}\n","/**\n * Centralized constants for the codegen system\n * Replaces magic strings scattered throughout generators\n */\n\n// ============================================================================\n// Field Types\n// ============================================================================\n\nexport const FIELD_TYPES = {\n STRING: 'string',\n NUMBER: 'number',\n BOOLEAN: 'boolean',\n TEXT: 'text',\n DECIMAL: 'decimal',\n VARCHAR: 'varchar',\n SERIAL: 'serial',\n DATE: 'date',\n TIMESTAMP: 'timestamp',\n TIME: 'time',\n MARKDOWN: 'markdown',\n IMAGE: 'image',\n VIDEO: 'video',\n MEDIA: 'media',\n ICON: 'icon',\n GROUP: 'group',\n TABS: 'tabs',\n LIST: 'list',\n SEPARATOR: 'separator',\n SECTION: 'section',\n SELECT: 'select',\n RELATIONSHIP: 'relationship',\n CURRICULUM: 'curriculum'\n} as const\n\nexport const LAYOUT_FIELD_TYPES = [FIELD_TYPES.SEPARATOR] as const\n\nexport const NESTED_FIELD_TYPES = [FIELD_TYPES.GROUP, FIELD_TYPES.TABS, FIELD_TYPES.LIST] as const\n\nexport const RICH_TEXT_FIELD_TYPES = [FIELD_TYPES.MARKDOWN, FIELD_TYPES.TEXT] as const\n\nexport const LONG_TEXT_FIELD_TYPES = [\n FIELD_TYPES.TEXT,\n FIELD_TYPES.MARKDOWN,\n FIELD_TYPES.LIST,\n FIELD_TYPES.MEDIA,\n FIELD_TYPES.VIDEO,\n FIELD_TYPES.CURRICULUM\n] as const\n\n// ============================================================================\n// Column Types\n// ============================================================================\n\nexport const COLUMN_TYPES = {\n TEXT: 'text',\n BADGE: 'badge',\n DATE: 'date',\n CUSTOM: 'custom',\n AVATAR: 'avatar',\n LINK: 'link',\n IMAGE: 'image',\n EMAIL: 'email',\n NUMBER: 'number',\n BOOLEAN: 'boolean'\n} as const\n\n// ============================================================================\n// Form Field Types\n// ============================================================================\n\nexport const FORM_FIELD_TYPES = {\n TEXT: 'text',\n TEXTAREA: 'textarea',\n EMAIL: 'email',\n PHONE: 'phone',\n NUMBER: 'number',\n URL: 'url',\n DATE: 'date',\n SELECT: 'select',\n RADIO: 'radio',\n CHECKBOX: 'checkbox',\n MULTISELECT: 'multiselect',\n FILE: 'file',\n UPLOAD: 'upload',\n GROUP: 'group',\n TIMEZONE: 'timezone',\n LIST: 'list'\n} as const\n\n// ============================================================================\n// Auto-generated Fields\n// ============================================================================\n\nexport const AUTO_FIELDS = {\n ID: 'id',\n CREATED_AT: 'createdAt',\n UPDATED_AT: 'updatedAt',\n PUBLISHED: 'published',\n SLUG: 'slug'\n} as const\n\nexport const FORM_SUBMISSION_FIELDS = {\n SUBMITTED_AT: 'submittedAt',\n IP_ADDRESS: 'ipAddress',\n USER_AGENT: 'userAgent'\n} as const\n\n// ============================================================================\n// Database Constants\n// ============================================================================\n\nexport const DRIZZLE_DEFAULTS = {\n VARCHAR_LENGTH: 255,\n DECIMAL_PRECISION: 10,\n DECIMAL_SCALE: 2\n} as const\n\n// ============================================================================\n// Generator Names\n// ============================================================================\n\nexport const CORE_GENERATORS = [\n 'database',\n 'actions',\n 'hooks',\n 'columns',\n 'table',\n 'page',\n 'page-content',\n 'form',\n 'create-page',\n 'edit-page',\n 'navigation'\n] as const\n\n// ============================================================================\n// File Extensions\n// ============================================================================\n\nexport const FILE_EXTENSIONS = {\n TYPESCRIPT: '.ts',\n TSX: '.tsx',\n JSON: '.json',\n SQL: '.sql'\n} as const\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport type FieldTypeValue = (typeof FIELD_TYPES)[keyof typeof FIELD_TYPES]\nexport type ColumnTypeValue = (typeof COLUMN_TYPES)[keyof typeof COLUMN_TYPES]\nexport type FormFieldTypeValue = (typeof FORM_FIELD_TYPES)[keyof typeof FORM_FIELD_TYPES]\n\nexport function isFieldType(value: string): value is FieldTypeValue {\n return Object.values(FIELD_TYPES).includes(value as FieldTypeValue)\n}\n\nexport function isLayoutField(type: string): boolean {\n return (LAYOUT_FIELD_TYPES as readonly string[]).includes(type)\n}\n\nexport function isNestedFieldType(type: string): boolean {\n return (NESTED_FIELD_TYPES as readonly string[]).includes(type)\n}\n\nexport function isLongTextFieldType(type: string): boolean {\n return (LONG_TEXT_FIELD_TYPES as readonly string[]).includes(type)\n}\n","/**\n * Shared helpers for entity and single action generators\n */\n\nimport { toTypeScriptType } from '../../core/type-mappers/index.js'\nimport type { SchemaField } from '../../types.js'\nimport { toCamelCase } from '../../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface ActionsGeneratorResult {\n files: string[]\n}\n\n// ============================================================================\n// Field Mapping Helpers\n// ============================================================================\n\nexport function generateFieldMapping(field: SchemaField, source = 'input'): string {\n if (field.type === 'list') return `${source}.${field.name} || []`\n if (\n (field.type === 'date' || field.type === 'timestamp' || field.type === 'time') &&\n !field.required\n ) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n if (!field.required && ['string', 'varchar', 'text', 'select'].includes(field.type)) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n return `${source}.${field.name}`\n}\n\nexport function getFieldType(field: SchemaField, mode: 'input' | 'output' = 'output'): string {\n return toTypeScriptType(field, mode)\n}\n\n// ============================================================================\n// Helper builders for relationship queries\n// ============================================================================\n\nexport function buildRelationshipSelect(\n allDbFields: SchemaField[],\n relationshipFields: SchemaField[],\n tableVar: string,\n htmlFields: SchemaField[] = []\n): string {\n const fieldSelects = allDbFields\n .filter((f) => f.type !== 'relationship')\n .map((f) => ` ${f.name}: ${tableVar}.${f.name}`)\n const htmlSelects = htmlFields.map((f) => ` ${f.name}Html: ${tableVar}.${f.name}Html`)\n const regularSelects = [...fieldSelects, ...htmlSelects].join(',\\n')\n\n const relSelects = relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return ` ${f.name}: { id: ${relTable}.id, name: ${relTable}.name, title: ${relTable}.title, slug: ${relTable}.slug, label: ${relTable}.label }`\n })\n .join(',\\n')\n\n const joins = relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return `.leftJoin(${relTable}, sql\\`CAST(NULLIF(\\${${tableVar}.${f.name}}, '') AS INTEGER) = \\${${relTable}.id}\\`)`\n })\n .join('')\n\n return `db.select({\\n${regularSelects},\\n${relSelects}\\n }).from(${tableVar})${joins}`\n}\n\nexport function buildResultMapping(\n allDbFields: SchemaField[],\n _relationshipFields: SchemaField[],\n Plural: string,\n camelPlural: string,\n Singular: string,\n hasListRels = false\n): string {\n const rowMappings = allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n return ` ${f.name}: row.${f.name}?.id ? { id: row.${f.name}.id, name: row.${f.name}.name ?? undefined, title: row.${f.name}.title ?? undefined, slug: row.${f.name}.slug ?? undefined, label: row.${f.name}.label ?? undefined } : null`\n }\n return ` ${f.name}: row.${f.name}`\n })\n .join(',\\n')\n\n const mapBlock = `\n\n const mapped${Plural} = results.map((row) => ({\n${rowMappings}\n }))`\n\n if (hasListRels) {\n return `${mapBlock}\n\n const populated${Plural} = await Promise.all(\n mapped${Plural}.map(record => populate${Singular}ListRelationships(record as ${Singular}Data))\n )\n\n return {\n ${camelPlural}: populated${Plural},\n total: populated${Plural}.length\n }`\n }\n\n return `${mapBlock}\n\n return {\n ${camelPlural}: mapped${Plural} as ${Singular}Data[],\n total: mapped${Plural}.length\n }`\n}\n\nexport function buildSingleRowMapping(\n allDbFields: SchemaField[],\n _relationshipFields: SchemaField[],\n typeName: string,\n htmlFields: SchemaField[] = []\n): string {\n const fieldMappings = allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n return ` ${f.name}: row.${f.name}?.id ? { id: row.${f.name}.id, name: row.${f.name}.name ?? undefined, title: row.${f.name}.title ?? undefined, slug: row.${f.name}.slug ?? undefined, label: row.${f.name}.label ?? undefined } : null`\n }\n return ` ${f.name}: row.${f.name}`\n })\n const htmlMappings = htmlFields.map((f) => ` ${f.name}Html: row.${f.name}Html`)\n const mappings = [...fieldMappings, ...htmlMappings].join(',\\n')\n\n return `{\\n${mappings}\\n } as ${typeName}`\n}\n\nexport function buildExplicitSelect(fields: SchemaField[], tableVar: string, htmlFields: SchemaField[] = []): string {\n const fieldSelects = fields.map((f) => ` ${f.name}: ${tableVar}.${f.name}`)\n const htmlSelects = htmlFields.map((f) => ` ${f.name}Html: ${tableVar}.${f.name}Html`)\n const selects = [...fieldSelects, ...htmlSelects].join(',\\n')\n return `db.select({\\n${selects}\\n }).from(${tableVar})`\n}\n\n// ============================================================================\n// List-relationship helpers\n// ============================================================================\n\nexport function findListFieldsWithRelationships(\n fields: SchemaField[]\n): Array<{ field: SchemaField; path: string[] }> {\n const result: Array<{ field: SchemaField; path: string[] }> = []\n for (const field of fields) {\n if (field.type === 'list' && field.fields) {\n const hasRels = field.fields.some((f) => f.type === 'relationship' && f.relationship)\n if (hasRels) {\n result.push({ field, path: [field.name] })\n }\n }\n }\n return result\n}\n\nexport function generatePopulateListRelsFunction(\n queries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n listFieldName: string\n }>,\n Singular: string\n): string {\n const blocks = queries.map((q) => {\n const v = `${q.fieldPath}_${q.relField.name}`\n return ` // ${q.listFieldName} -> ${q.relField.name}\n const ${v}Ids = record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})\n ? (record.${q.listFieldName} as Record<string, unknown>[])\n .map((item) => item.${q.relField.name})\n .filter((id) => id != null && id !== '')\n .map((id) => Number.parseInt(String(id), 10))\n .filter((id) => !Number.isNaN(id))\n : []\n\n const ${v}Results = ${v}Ids.length > 0\n ? await db.select().from(${q.relTable}).where(inArray(${q.relTable}.id, ${v}Ids))\n : []\n\n const ${v}Map = new Map(${v}Results.map((r) => [r.id, r]))\n\n if (record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})) {\n record.${q.listFieldName} = (record.${q.listFieldName} as Record<string, unknown>[]).map((item) => {\n const relId = item.${q.relField.name} ? Number.parseInt(String(item.${q.relField.name}), 10) : null\n return {\n ...item,\n ${q.relField.name}: relId && !Number.isNaN(relId) ? ${v}Map.get(relId) || null : null\n }\n })\n }`\n })\n\n return `\n/**\n * Populate relationship fields inside list (JSONB) fields\n */\nasync function populate${Singular}ListRelationships(record: ${Singular}Data): Promise<${Singular}Data> {\n${blocks.join('\\n\\n')}\n\n return record\n}\n`\n}\n","/**\n * Content generators for individual entity action files.\n * Each function returns the string content for one generated file.\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize } from '../../utils/string.js'\n\n/** Shared context for all entity file generators */\nexport interface EntityCtx {\n singular: string\n plural: string\n Singular: string\n Plural: string\n tableVar: string\n camelSingular: string\n camelPlural: string\n cacheTag: string\n hasRelationships: boolean\n hasM2M: boolean\n hasListRels: boolean\n hasHtmlOutput: boolean\n hasSlug: boolean\n hasDraft: boolean\n hasSearch: boolean\n hasFilters: boolean\n hasAutoSlug: boolean\n searchFields: string[]\n htmlOutputFields: SchemaField[]\n m2mFields: SchemaField[]\n filterableFields: SchemaField[]\n relTableImports: string[]\n listRelTableImports: string[]\n // Pre-computed template fragments\n dataInterface: string\n displayDataInterface: string\n responseInterface: string\n filtersInterface: string\n createInterface: string\n updateInterface: string\n selectClause: string\n listSelectClause: string\n displaySelectClause: string\n filterConditions: string\n searchBlock: string\n resultMapping: string\n listResultMapping: string\n singleRowReturn: string\n displaySingleRowReturn: string\n fieldMeta: string\n createMappings: string\n htmlCreateBlock: string\n htmlCreateMappings: string\n autoSlugCreate: string\n autoSlugUpdate: string\n populateListRelsFn: string\n filters: Array<{ field: string }>\n}\n\n// ============================================================================\n// types.ts\n// ============================================================================\n\nexport function genTypesContent(ctx: EntityCtx): string {\n const parts = [\n ctx.dataInterface,\n ctx.displayDataInterface || null,\n ctx.responseInterface,\n ctx.filtersInterface,\n ctx.createInterface,\n `export interface Create${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n ${ctx.camelSingular}?: ${ctx.Singular}Data\\n}`,\n ctx.updateInterface,\n `export interface Update${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n ${ctx.camelSingular}?: ${ctx.Singular}Data\\n}`,\n `export interface Delete${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n}`,\n `export const CACHE_TAG = '${ctx.cacheTag}'`\n ]\n return parts.filter(Boolean).join('\\n\\n') + '\\n'\n}\n\n// ============================================================================\n// helpers.ts (conditional)\n// ============================================================================\n\nexport function genHelpersContent(ctx: EntityCtx): string | null {\n if (!ctx.hasListRels) return null\n\n const lines: string[] = []\n\n lines.push(`import db from '@cms/db'`)\n const tables = [...new Set(ctx.listRelTableImports)].sort()\n if (tables.length > 0) {\n lines.push(`import { ${tables.join(', ')} } from '@cms/db/schema'`)\n }\n lines.push(`import { inArray } from 'drizzle-orm'`)\n lines.push(`import type { ${ctx.Singular}Data } from './types'`)\n lines.push('')\n\n const exportedFn = ctx.populateListRelsFn\n .replace('async function', 'export async function')\n .trim()\n lines.push(exportedFn)\n lines.push('')\n\n return lines.join('\\n')\n}\n\n// ============================================================================\n// get-{plural}.ts\n// ============================================================================\n\nexport function genGetPluralContent(ctx: EntityCtx): string {\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['asc']\n if (ctx.hasSearch || ctx.filterableFields.length > 1) drizzle.push('and')\n if (ctx.hasSearch) drizzle.push('ilike', 'or')\n if (ctx.filterableFields.some(() => true)) drizzle.push('eq')\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const typeImports = [`${ctx.Plural}Response`, `Get${ctx.Plural}Filters`, `${ctx.Singular}Data`]\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${typeImports.sort().join(', ')} } from './types'${populateImport}\n\nexport async function get${ctx.Plural}(filters?: Get${ctx.Plural}Filters): Promise<${ctx.Plural}Response> {\n try {\n const conditions = []\n${ctx.searchBlock}${ctx.filterConditions}\n\n const query = ${ctx.listSelectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${ctx.tableVar}.sortOrder))\n : query.orderBy(asc(${ctx.tableVar}.sortOrder))\n\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery${ctx.listResultMapping}\n } catch (error) {\n console.error('Error fetching ${ctx.plural}:', error)\n return { ${ctx.camelPlural}: [], total: 0 }\n }\n}\n`\n}\n\n// ============================================================================\n// get-{singular}-by-id.ts\n// ============================================================================\n\nexport function genGetByIdContent(ctx: EntityCtx): string {\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['eq']\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${ctx.Singular}Data } from './types'${populateImport}\n\nexport async function get${ctx.Singular}ById(id: number): Promise<${ctx.Singular}Data | null> {\n try {\n const result = await ${ctx.selectClause}.where(eq(${ctx.tableVar}.id, id)).limit(1)\n if (result.length === 0) return null\n ${ctx.singleRowReturn}\n } catch (error) {\n console.error('Error fetching ${ctx.singular}:', error)\n return null\n }\n}\n`\n}\n\n// ============================================================================\n// get-{singular}-by-slug.ts (conditional)\n// ============================================================================\n\nexport function genGetBySlugContent(ctx: EntityCtx): string | null {\n if (!ctx.hasSlug) return null\n const returnType = ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : `${ctx.Singular}Data`\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['eq']\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const typeImport = ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : `${ctx.Singular}Data`\n const extraTypes = ctx.hasListRels && ctx.hasHtmlOutput ? `, ${ctx.Singular}Data` : ''\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${typeImport}${extraTypes} } from './types'${populateImport}\n\nexport async function get${ctx.Singular}BySlug(slug: string): Promise<${returnType} | null> {\n try {\n const result = await ${ctx.displaySelectClause}.where(eq(${ctx.tableVar}.slug, slug)).limit(1)\n if (result.length === 0) return null\n ${ctx.displaySingleRowReturn}\n } catch (error) {\n console.error('Error fetching ${ctx.singular} by slug:', error)\n return null\n }\n}\n`\n}\n\n// ============================================================================\n// create-{singular}.ts\n// ============================================================================\n\nexport function genCreateContent(ctx: EntityCtx): string {\n const slugImport = ctx.hasAutoSlug ? `\\nimport { slugify } from '@cms/utils/validation'` : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { desc } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Create${ctx.Singular}Input, Create${ctx.Singular}Result, ${ctx.Singular}Data } from './types'${slugImport}\n\nexport async function create${ctx.Singular}(input: Create${ctx.Singular}Input): Promise<Create${ctx.Singular}Result> {\n try {${ctx.autoSlugCreate}\n const maxSortOrderResult = await db\n .select({ maxOrder: ${ctx.tableVar}.sortOrder })\n .from(${ctx.tableVar})\n .orderBy(desc(${ctx.tableVar}.sortOrder))\n .limit(1)\n const nextSortOrder = (maxSortOrderResult[0]?.maxOrder ?? 0) + 1\n${ctx.htmlCreateBlock}\n const result = await db.insert(${ctx.tableVar}).values({\n${ctx.createMappings},${ctx.hasHtmlOutput ? `\\n${ctx.htmlCreateMappings},` : ''}${ctx.hasDraft ? `\\n published: input.published ?? false,` : ''}\n sortOrder: nextSortOrder,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString()\n }).returning()\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${ctx.camelSingular}: result[0] as ${ctx.Singular}Data\n }\n } catch (error) {\n console.error('Error creating ${ctx.singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to create ${ctx.singular}')\n }\n}\n`\n}\n\n// ============================================================================\n// update-{singular}.ts\n// ============================================================================\n\nexport function genUpdateContent(ctx: EntityCtx): string {\n const slugImport = ctx.hasAutoSlug ? `\\nimport { slugify } from '@cms/utils/validation'` : ''\n const htmlUpdateBlock = ctx.hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n ctx.htmlOutputFields.map((f) => ` if (processedData.${f.name} !== undefined) {\\n processedData.${f.name}Html = renderMarkdownSync(String(processedData.${f.name} || ''))\\n }`).join('\\n') + '\\n'\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Update${ctx.Singular}Input, Update${ctx.Singular}Result, ${ctx.Singular}Data } from './types'${slugImport}\n\nexport async function update${ctx.Singular}(input: Update${ctx.Singular}Input): Promise<Update${ctx.Singular}Result> {\n try {\n const { id, ...updateData } = input\n${ctx.autoSlugUpdate}\n const fieldMeta = [\n ${ctx.fieldMeta}\n ]\n\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(updateData)) {\n if (key === 'published') { processedData[key] = value; continue }\n const field = fieldMeta.find(f => f.name === key)\n if (!field) continue\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (!field.required && ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n${htmlUpdateBlock}\n const result = await db.update(${ctx.tableVar})\n .set({ ...processedData, updatedAt: new Date().toISOString() })\n .where(eq(${ctx.tableVar}.id, id))\n .returning()\n\n if (result.length === 0) throw new Error('${ctx.Singular} not found')\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${ctx.camelSingular}: result[0] as ${ctx.Singular}Data\n }\n } catch (error) {\n console.error('Error updating ${ctx.singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to update ${ctx.singular}')\n }\n}\n`\n}\n\n// ============================================================================\n// delete-{singular}.ts\n// ============================================================================\n\nexport function genDeleteContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Delete${ctx.Singular}Result } from './types'\n\nexport async function delete${ctx.Singular}(id: number): Promise<Delete${ctx.Singular}Result> {\n try {\n await db.delete(${ctx.tableVar}).where(eq(${ctx.tableVar}.id, id))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error deleting ${ctx.singular}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to delete ${ctx.singular}' }\n }\n}\n`\n}\n\n// ============================================================================\n// delete-bulk-{plural}.ts\n// ============================================================================\n\nexport function genDeleteBulkContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { inArray } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Delete${ctx.Singular}Result } from './types'\n\nexport async function deleteBulk${ctx.Plural}(ids: number[]): Promise<Delete${ctx.Singular}Result> {\n try {\n if (ids.length === 0) return { success: false, error: 'No items selected for deletion' }\n await db.delete(${ctx.tableVar}).where(inArray(${ctx.tableVar}.id, ids))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error deleting ${ctx.plural}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to delete ${ctx.plural}' }\n }\n}\n`\n}\n\n// ============================================================================\n// update-{singular}-sort-order.ts\n// ============================================================================\n\nexport function genSortOrderContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { asc, desc, eq, gt, lt } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function update${ctx.Singular}SortOrder(\n id: number,\n direction: 'up' | 'down'\n): Promise<{ success: boolean; error?: string }> {\n try {\n const current = await db.select({ id: ${ctx.tableVar}.id, sortOrder: ${ctx.tableVar}.sortOrder }).from(${ctx.tableVar}).where(eq(${ctx.tableVar}.id, id)).limit(1)\n if (current.length === 0) return { success: false, error: '${ctx.Singular} not found' }\n\n const currentSortOrder = current[0].sortOrder\n const adjacent = await db\n .select({ id: ${ctx.tableVar}.id, sortOrder: ${ctx.tableVar}.sortOrder })\n .from(${ctx.tableVar})\n .where(direction === 'up' ? lt(${ctx.tableVar}.sortOrder, currentSortOrder) : gt(${ctx.tableVar}.sortOrder, currentSortOrder))\n .orderBy(direction === 'up' ? desc(${ctx.tableVar}.sortOrder) : asc(${ctx.tableVar}.sortOrder))\n .limit(1)\n\n if (adjacent.length === 0) return { success: true }\n\n await db.update(${ctx.tableVar}).set({ sortOrder: adjacent[0].sortOrder }).where(eq(${ctx.tableVar}.id, id))\n await db.update(${ctx.tableVar}).set({ sortOrder: currentSortOrder }).where(eq(${ctx.tableVar}.id, adjacent[0].id))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error updating sort order:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to update sort order' }\n }\n}\n`\n}\n\n// ============================================================================\n// bulk-update-{plural}-sort-order.ts\n// ============================================================================\n\nexport function genBulkSortOrderContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function bulkUpdate${ctx.Plural}SortOrder(\n updates: Array<{ id: number; sortOrder: number }>\n): Promise<{ success: boolean; error?: string }> {\n try {\n if (updates.length === 0) return { success: true }\n await Promise.all(updates.map((u) => db.update(${ctx.tableVar}).set({ sortOrder: u.sortOrder }).where(eq(${ctx.tableVar}.id, u.id))))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error bulk updating sort order:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to bulk update sort order' }\n }\n}\n`\n}\n\n// ============================================================================\n// M2M files: get-{rel}-for-{singular}.ts and set-{rel}-for-{singular}.ts\n// ============================================================================\n\nexport function genM2MFiles(ctx: EntityCtx): Array<{ name: string; content: string }> {\n const files: Array<{ name: string; content: string }> = []\n\n for (const f of ctx.m2mFields) {\n const rel = f.relationship || ''\n const RelPascal = toPascalCase(rel)\n const relSingular = singularize(rel)\n const junctionVar = toCamelCase(`${ctx.singular}${RelPascal}`)\n const entityIdCol = `${ctx.singular}Id`\n const relIdCol = `${relSingular}Id`\n const kebabRel = rel.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n\n // get file\n files.push({\n name: `get-${kebabRel}-for-${ctx.singular}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${junctionVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\n\nexport async function get${RelPascal}For${ctx.Singular}(${ctx.singular}Id: number): Promise<number[]> {\n try {\n const results = await db.select({ ${relIdCol}: ${junctionVar}.${relIdCol} }).from(${junctionVar}).where(eq(${junctionVar}.${entityIdCol}, ${ctx.singular}Id))\n return results.map(r => r.${relIdCol})\n } catch (error) {\n console.error('Error fetching ${rel} for ${ctx.singular}:', error)\n return []\n }\n}\n`\n })\n\n // set file\n files.push({\n name: `set-${kebabRel}-for-${ctx.singular}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${junctionVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function set${RelPascal}For${ctx.Singular}(${ctx.singular}Id: number, ${rel}Ids: number[]): Promise<{ success: boolean; error?: string }> {\n try {\n await db.delete(${junctionVar}).where(eq(${junctionVar}.${entityIdCol}, ${ctx.singular}Id))\n if (${rel}Ids.length > 0) {\n await db.insert(${junctionVar}).values(${rel}Ids.map(${relSingular}Id => ({ ${entityIdCol}: ${ctx.singular}Id, ${relIdCol}: ${relSingular}Id })))\n }\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error setting ${rel} for ${ctx.singular}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to set ${rel}' }\n }\n}\n`\n })\n }\n\n return files\n}\n\n// ============================================================================\n// get-distinct-{plural}-{field}.ts files\n// ============================================================================\n\nexport function genDistinctFiles(ctx: EntityCtx): Array<{ name: string; content: string }> {\n if (!ctx.hasFilters) return []\n\n return ctx.filters.map((filter) => {\n const fieldPascal = toPascalCase(filter.field)\n const kebabField = filter.field.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n const kebabPlural = ctx.plural.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n\n return {\n name: `get-distinct-${kebabPlural}-${kebabField}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { asc, isNotNull } from 'drizzle-orm'\n\nexport async function getDistinct${ctx.Plural}${fieldPascal}(): Promise<string[]> {\n try {\n const results = await db\n .selectDistinct({ value: ${ctx.tableVar}.${filter.field} })\n .from(${ctx.tableVar})\n .where(isNotNull(${ctx.tableVar}.${filter.field}))\n .orderBy(asc(${ctx.tableVar}.${filter.field}))\n return results.map((r) => String(r.value)).filter(Boolean)\n } catch (error) {\n console.error('Error fetching distinct ${ctx.plural} ${filter.field}:', error)\n return []\n }\n}\n`\n }\n })\n}\n\n// ============================================================================\n// index.ts (barrel)\n// ============================================================================\n\nexport function genBarrelContent(\n files: Array<{ name: string; content: string }>,\n ctx: EntityCtx\n): string {\n const lines: string[] = []\n\n // Re-export types\n const typeNames: string[] = [\n `${ctx.Singular}Data`,\n ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : null,\n `${ctx.Plural}Response`,\n `Get${ctx.Plural}Filters`,\n `Create${ctx.Singular}Input`,\n `Create${ctx.Singular}Result`,\n `Update${ctx.Singular}Input`,\n `Update${ctx.Singular}Result`,\n `Delete${ctx.Singular}Result`,\n ].filter(Boolean) as string[]\n lines.push(`export type { ${typeNames.join(', ')} } from './types'`)\n lines.push('')\n\n // Re-export action functions from each file (skip types.ts, helpers.ts, index.ts)\n for (const file of files) {\n if (file.name === 'types.ts' || file.name === 'helpers.ts') continue\n // Extract exported function names from the content\n const exportMatches = file.content.matchAll(/export async function (\\w+)/g)\n const fnNames = [...exportMatches].map((m) => m[1])\n if (fnNames.length > 0) {\n const modulePath = './' + file.name.replace(/\\.ts$/, '')\n lines.push(`export { ${fnNames.join(', ')} } from '${modulePath}'`)\n }\n }\n\n lines.push('')\n return lines.join('\\n')\n}\n","/**\n * Generator 2b: Server actions for single (singleton) schemas\n * Split into individual files: types.ts, get-{singular}.ts, upsert-{singular}.ts, index.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields } from '../../core/field-helpers/index.js'\nimport type { Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, toKebabCase, quotePropertyName } from '../../utils/string.js'\nimport type { ActionsGeneratorResult } from './action-helpers.js'\nimport { generateFieldMapping, getFieldType } from './action-helpers.js'\n\n/**\n * Generate server actions for a single (singleton) schema, split into individual files.\n */\nexport function generateSingleActions(\n schema: Schema,\n cwd: string,\n actionsDir: string,\n options: { force?: boolean } = {}\n): ActionsGeneratorResult {\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, schema.name)\n const oldFilePath = path.join(absActionsDir, `${schema.name}.ts`)\n\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const tableVar = toCamelCase(schema.name)\n const camelSingular = toCamelCase(singular)\n const kebabSingular = toKebabCase(singular)\n\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true) && !isLayoutField(f.type)\n )\n\n const htmlOutputFields = dbFields.filter(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n const hasHtmlOutput = htmlOutputFields.length > 0\n\n const allDbFields = [...dbFields]\n if (!dbFields.some((f) => f.name === 'createdAt')) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!dbFields.some((f) => f.name === 'updatedAt')) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n\n const upsertFields = dbFields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n\n // --- Build types ---\n const dataFields = allDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const htmlFieldTypes = htmlOutputFields.map((f) => ` ${f.name}Html: string`).join('\\n')\n\n const upsertInterfaceFields = upsertFields\n .map(\n (f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`\n )\n .join('\\n')\n\n const fieldMeta = upsertFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const upsertMappings = upsertFields\n .map((f) => ` ${f.name}: ${generateFieldMapping(f)}`)\n .join(',\\n')\n\n const cacheTag = `${schema.name}:all`\n\n // --- types.ts ---\n const typesContent = [\n `export interface ${Singular}Data {\\n${dataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}\\n}`,\n `export interface Upsert${Singular}Input {\\n${upsertInterfaceFields}\\n}`,\n `export interface Upsert${Singular}Result {\\n success: boolean\\n error?: string\\n ${camelSingular}?: ${Singular}Data\\n}`,\n `export const CACHE_TAG = '${cacheTag}'`\n ].join('\\n\\n') + '\\n'\n\n // --- get-{singular}.ts ---\n const getContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport type { ${Singular}Data } from './types'\n\nexport async function get${Singular}(): Promise<${Singular}Data | null> {\n try {\n const result = await db.select().from(${tableVar}).where(eq(${tableVar}.id, 1)).limit(1)\n if (result.length === 0) return null\n return result[0] as ${Singular}Data\n } catch (error) {\n console.error('Error fetching ${singular}:', error)\n return null\n }\n}\n`\n\n // --- upsert-{singular}.ts ---\n const htmlUpsertBlock = hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n htmlOutputFields.map((f) => ` if (processedData.${f.name} !== undefined) {\\n processedData.${f.name}Html = renderMarkdownSync(String(processedData.${f.name} || ''))\\n }`).join('\\n') + '\\n' +\n htmlOutputFields.map((f) => ` const ${f.name}Html = renderMarkdownSync(input.${f.name} || '')`).join('\\n') + '\\n'\n : ''\n const htmlUpsertMappings = hasHtmlOutput\n ? '\\n' + htmlOutputFields.map((f) => ` ${f.name}Html`).join(',\\n') + ','\n : ''\n\n const upsertContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableVar} } from '@cms/db/schema'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Upsert${Singular}Input, Upsert${Singular}Result, ${Singular}Data } from './types'\n\nexport async function upsert${Singular}(input: Upsert${Singular}Input): Promise<Upsert${Singular}Result> {\n try {\n const fieldMeta = [\n ${fieldMeta}\n ]\n\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(input)) {\n const field = fieldMeta.find(f => f.name === key)\n if (!field) continue\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (!field.required && ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n${htmlUpsertBlock}\n const now = new Date().toISOString()\n\n const result = await db\n .insert(${tableVar})\n .values({\n id: 1,\n ...processedData,\n createdAt: now,\n updatedAt: now\n })\n .onConflictDoUpdate({\n target: ${tableVar}.id,\n set: { ...processedData, updatedAt: now }\n })\n .returning()\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${camelSingular}: result[0] as ${Singular}Data\n }\n } catch (error) {\n console.error('Error upserting ${singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to save ${singular}')\n }\n}\n`\n\n // --- index.ts (barrel) ---\n const barrelContent = `export type { ${Singular}Data, Upsert${Singular}Input, Upsert${Singular}Result } from './types'\nexport { get${Singular} } from './get-${kebabSingular}'\nexport { upsert${Singular} } from './upsert-${kebabSingular}'\n`\n\n // Write all files\n const files = [\n { name: 'types.ts', content: typesContent },\n { name: `get-${kebabSingular}.ts`, content: getContent },\n { name: `upsert-${kebabSingular}.ts`, content: upsertContent },\n { name: 'index.ts', content: barrelContent }\n ]\n\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.join(actionsDir, schema.name, f.name)) }\n}\n","/**\n * Generator 12: Cache module — cms/lib/cache/\n * Generates tags, cached queries, and revalidation helpers for all schemas\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toScreamingSnake } from '../utils/string.js'\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\ninterface NestedLookupConfig {\n name: string\n pascalName: string\n camelName: string\n screamingSnake: string\n slugField: string\n}\n\ninterface CacheConfig {\n name: string\n singularName: string\n pluralName: string\n pascalSingular: string\n pascalPlural: string\n screamingSnake: string\n hasSlug: boolean\n isSingle: boolean\n nestedLookups: NestedLookupConfig[]\n}\n\n// ============================================================================\n// Schema Loading\n// ============================================================================\n\nfunction loadAllSchemas(cwd: string, schemasDir: string): Schema[] {\n const dir = path.join(cwd, schemasDir)\n if (!fs.existsSync(dir)) return []\n\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'))\n const seen = new Map<string, Schema>()\n\n for (const file of files) {\n if (file === 'schema.json') continue // skip metaschema\n const content = fs.readFileSync(path.join(dir, file), 'utf-8')\n const schema = JSON.parse(content) as Schema\n if (!schema.name) continue // skip non-entity JSON files\n seen.set(schema.name, schema)\n }\n\n return Array.from(seen.values())\n}\n\nfunction buildCacheConfig(schema: Schema): CacheConfig {\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const dbFields = flattenFields(schema.fields)\n const hasSlug = dbFields.some((f) => f.name === 'slug')\n\n const nestedLookups: NestedLookupConfig[] = (schema.nestedSlugLookups || []).map((lookup) => ({\n name: lookup.name,\n pascalName: toPascalCase(lookup.name),\n camelName: toCamelCase(lookup.name),\n screamingSnake: toScreamingSnake(lookup.name),\n slugField: lookup.slugField || 'slug'\n }))\n\n return {\n name: schema.name,\n singularName,\n pluralName,\n pascalSingular: toPascalCase(singularName),\n pascalPlural: toPascalCase(pluralName),\n screamingSnake: toScreamingSnake(pluralName),\n hasSlug,\n isSingle: schema.type === 'single',\n nestedLookups\n }\n}\n\n// ============================================================================\n// File Generators\n// ============================================================================\n\nfunction generateTags(configs: CacheConfig[]): string {\n const entries: string[] = []\n\n for (const c of configs) {\n entries.push(` ${c.screamingSnake}_ALL: '${c.pluralName}:all'`)\n\n if (c.isSingle) continue // single schemas only need the ALL tag\n\n if (c.hasSlug) {\n entries.push(\n ` ${c.screamingSnake}_BY_SLUG: (slug: string) => \\`${c.pluralName}:slug:\\${slug}\\``\n )\n }\n\n for (const n of c.nestedLookups) {\n entries.push(\n ` ${c.screamingSnake}_${n.screamingSnake}_BY_SLUG: (${c.singularName}Slug: string, ${n.camelName}Slug: string) => \\`${c.pluralName}:\\${${c.singularName}Slug}:${n.name}:\\${${n.camelName}Slug}\\``\n )\n }\n }\n\n entries.sort()\n\n return `/**\n * Cache tag constants for Next.js 'use cache' invalidation\n * AUTO-GENERATED — do not edit directly\n */\n\nexport const CACHE_TAGS = {\n${entries.join(',\\n')}\n} as const\n`\n}\n\nfunction generateCachedQueries(configs: CacheConfig[]): string {\n const actionImports: string[] = []\n const typeImportsBySchema = new Map<string, string[]>()\n const fns: string[] = []\n\n for (const c of configs) {\n if (c.isSingle) {\n // Single schema: getCachedXxx() with no filters\n actionImports.push(`get${c.pascalSingular}`)\n\n fns.push(`\nexport const getCached${c.pascalSingular} = async () => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalSingular}()\n}`)\n continue\n }\n\n // Entity schema: getCachedXxxPlural(filters) + slug lookups\n actionImports.push(`get${c.pascalPlural}`)\n const types = typeImportsBySchema.get(c.name) || []\n types.push(`Get${c.pascalPlural}Filters`)\n typeImportsBySchema.set(c.name, types)\n\n if (c.hasSlug) actionImports.push(`get${c.pascalSingular}BySlug`)\n for (const n of c.nestedLookups) actionImports.push(`get${n.pascalName}BySlug`)\n\n fns.push(`\nexport const getCached${c.pascalPlural} = async (filters?: Get${c.pascalPlural}Filters) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalPlural}(filters)\n}`)\n\n if (c.hasSlug) {\n fns.push(`\nexport const getCached${c.pascalSingular}BySlug = async (slug: string) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_BY_SLUG(slug))\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalSingular}BySlug(slug)\n}`)\n }\n\n for (const n of c.nestedLookups) {\n fns.push(`\nexport const getCached${n.pascalName}BySlug = async (${c.singularName}Slug: string, ${n.camelName}Slug: string) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_${n.screamingSnake}_BY_SLUG(${c.singularName}Slug, ${n.camelName}Slug))\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${n.pascalName}BySlug(${c.singularName}Slug, ${n.camelName}Slug)\n}`)\n }\n }\n\n actionImports.sort()\n\n const typeImportStr =\n typeImportsBySchema.size > 0\n ? `${Array.from(typeImportsBySchema.entries())\n .map(([schemaName, types]) => `import type { ${types.sort().join(', ')} } from '@cms/actions/${schemaName}'`)\n .join('\\n')}\\n`\n : ''\n\n // Group action imports by schema\n const actionsBySchema = new Map<string, string[]>()\n for (const c of configs) {\n if (c.isSingle) {\n actionsBySchema.set(c.name, [`get${c.pascalSingular}`])\n continue\n }\n const names: string[] = [`get${c.pascalPlural}`]\n if (c.hasSlug) names.push(`get${c.pascalSingular}BySlug`)\n for (const n of c.nestedLookups) names.push(`get${n.pascalName}BySlug`)\n actionsBySchema.set(c.name, names)\n }\n\n const actionImportLines = Array.from(actionsBySchema.entries())\n .map(([name, fns]) => `import { ${fns.join(', ')} } from '@cms/actions/${name}'`)\n .join('\\n')\n\n return `'use cache'\n\n/**\n * Cached query functions for Next.js 'use cache'\n * AUTO-GENERATED — do not edit directly\n */\n\nimport { cacheLife, cacheTag } from 'next/cache'\n${typeImportStr}${actionImportLines}\nimport { CACHE_TAGS } from './tags'\n${fns.join('\\n')}\n`\n}\n\nfunction generateRevalidate(configs: CacheConfig[]): string {\n const fns: string[] = []\n\n for (const c of configs) {\n if (c.isSingle) {\n fns.push(`\nexport const revalidate${c.pascalSingular} = async () => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n continue\n }\n\n fns.push(`\nexport const revalidate${c.pascalPlural} = async () => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n\n if (c.hasSlug) {\n fns.push(`\nexport const revalidate${c.pascalSingular}BySlug = async (slug: string) => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_BY_SLUG(slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n\n for (const n of c.nestedLookups) {\n fns.push(`\nexport const revalidate${n.pascalName}BySlug = async (${c.singularName}Slug: string, ${n.camelName}Slug: string) => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_${n.screamingSnake}_BY_SLUG(${c.singularName}Slug, ${n.camelName}Slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n }\n\n return `'use server'\n\n/**\n * Revalidation helpers for Next.js cache invalidation\n * AUTO-GENERATED — do not edit directly\n */\n\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAGS } from './tags'\n\nconst REVALIDATION_STRATEGY = 'max' as const\n${fns.join('\\n')}\n`\n}\n\nfunction generateIndex(): string {\n return `/**\n * Cache module exports\n * AUTO-GENERATED — do not edit directly\n */\n\nexport * from './tags'\nexport * from './cached-queries'\nexport * from './cached-queries-custom'\nexport * from './revalidate'\n`\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface CacheGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate all cache files based on all schemas in cms/schemas/\n */\nexport function generateCache(\n _schema: Schema,\n cwd: string,\n cmsDir: string,\n _options: GeneratorOptions = {}\n): CacheGeneratorResult {\n const cacheDir = path.join(cwd, cmsDir, 'lib', 'cache')\n const schemasDir = path.join(cmsDir, 'schemas')\n\n // Load all schemas and build configs (skip form schemas — they have no cacheable queries)\n const isFormSchema = (s: Schema) => 'submitButtonText' in s || 'steps' in s\n const schemas = loadAllSchemas(cwd, schemasDir).filter((s) => s.fields && !isFormSchema(s))\n const configs = schemas.map(buildCacheConfig).sort((a, b) => a.name.localeCompare(b.name))\n\n if (!fs.existsSync(cacheDir)) {\n fs.mkdirSync(cacheDir, { recursive: true })\n }\n\n const files: string[] = []\n\n // tags.ts\n fs.writeFileSync(path.join(cacheDir, 'tags.ts'), generateTags(configs), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'tags.ts'))\n\n // cached-queries.ts\n fs.writeFileSync(\n path.join(cacheDir, 'cached-queries.ts'),\n generateCachedQueries(configs),\n 'utf-8'\n )\n files.push(path.join(cmsDir, 'lib', 'cache', 'cached-queries.ts'))\n\n // revalidate.ts\n fs.writeFileSync(path.join(cacheDir, 'revalidate.ts'), generateRevalidate(configs), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'revalidate.ts'))\n\n // cached-queries-custom.ts (user-maintained, scaffold only if missing)\n const customQueriesPath = path.join(cacheDir, 'cached-queries-custom.ts')\n if (!fs.existsSync(customQueriesPath)) {\n fs.writeFileSync(\n customQueriesPath,\n `/**\\n * Custom cached query functions (not auto-generated)\\n * Add your custom cached queries here.\\n */\\n\\nexport {}\\n`,\n 'utf-8'\n )\n files.push(path.join(cmsDir, 'lib', 'cache', 'cached-queries-custom.ts'))\n }\n\n // index.ts\n fs.writeFileSync(path.join(cacheDir, 'index.ts'), generateIndex(), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'index.ts'))\n\n return { files }\n}\n","/**\n * Generator 4: Column definitions — (authenticated)/<n>/columns.tsx\n * Generates TanStack Table column definitions for entity list views\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../../types.js'\nimport { toPascalCase, singularize, pluralize } from '../../utils/string.js'\nimport {\n generateColumnDef,\n generateFirstColumnDef,\n generateTitleFallback,\n isSortableColumn\n} from './column-defs.js'\nimport {\n generateDeleteActionTemplate,\n generateReorderButtonsTemplate,\n generateTruncateHelper\n} from './column-actions.js'\nimport { createCustomCellComponent } from './custom-cell.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface ColumnsGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate column definitions for entity list view\n */\nexport function generateColumns(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): ColumnsGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const columnsFilePath = path.join(entityDir, 'columns.tsx')\n\n if (fs.existsSync(columnsFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n\n const flatFields = flattenFields(schema.fields || [])\n const titleFallback = generateTitleFallback(flatFields)\n\n // --- Determine needed imports ---\n let needsArrowUpDown = false\n let needsBadge = false\n let needsButton = true // Always for actions column\n let needsAvatar = false\n let needsTruncate = false\n let needsReactQueryClient = false\n let needsToast = false\n let needsAlertDialog = false\n let needsTrash = false\n\n for (const column of schema.columns) {\n if (isSortableColumn(column)) {\n needsArrowUpDown = true\n needsButton = true\n }\n if (column.type === 'badge' || column.type === 'boolean') needsBadge = true\n if (column.type === 'image' || column.type === 'avatar') needsAvatar = true\n if (column.type === 'link') needsTruncate = true\n }\n\n const hasEdit = schema.actions?.edit ?? false\n const hasDelete = schema.actions?.delete ?? false\n if (hasDelete) {\n needsTrash = true\n needsAlertDialog = true\n needsReactQueryClient = true\n needsToast = true\n }\n\n // --- Build lucide icons ---\n const lucideIcons: string[] = []\n if (needsArrowUpDown) lucideIcons.push('ArrowUpDown')\n lucideIcons.push('ChevronDown', 'ChevronUp', 'Edit')\n if (needsTrash) lucideIcons.push('Trash')\n\n // --- Build UI component imports (individual per-component) ---\n const uiImports: string[] = []\n if (needsButton) uiImports.push(\"import { Button } from '@cms/components/ui/button'\")\n if (needsBadge) uiImports.push(\"import { Badge } from '@cms/components/ui/badge'\")\n uiImports.push(\"import { Checkbox } from '@cms/components/ui/checkbox'\")\n if (needsAvatar) {\n uiImports.push(\n \"import { Avatar, AvatarImage, AvatarFallback } from '@cms/components/ui/avatar'\"\n )\n }\n if (needsAlertDialog) {\n uiImports.push(`import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger\n} from '@cms/components/ui/alert-dialog'`)\n }\n\n // --- Custom component imports ---\n const customImports: string[] = []\n for (const column of schema.columns) {\n if (column.type === 'custom' && column.component) {\n customImports.push(`import { ${column.component} } from './cells/${column.component}'`)\n createCustomCellComponent(schema, column.component, cwd, pagesDir, options)\n }\n }\n\n // --- Action imports ---\n const actionImports: string[] = []\n if (hasDelete) actionImports.push(`delete${Singular}`)\n\n // --- Generate columns ---\n const firstColumn = schema.columns[0]\n const restColumns = schema.columns.slice(1)\n\n const firstColDef = generateFirstColumnDef(firstColumn, flatFields, schema.name)\n const restColDefs = restColumns.map((col) => generateColumnDef(col, flatFields)).join(',\\n')\n\n // --- Delete handler ---\n const deleteHandler = hasDelete\n ? generateDeleteActionTemplate({ Singular, singular, plural })\n : ''\n\n // --- Reorder handler ---\n const reorderHandler = generateReorderButtonsTemplate()\n\n // --- Reorder column ---\n const reorderColumn = ` {\n id: 'reorder',\n header: () => <span className=\"sr-only\">Reorder</span>,\n cell: ({ row, table }) => {\n const reorderMode = table.options.meta?.reorderMode\n const onMoveRow = table.options.meta?.onMoveRow\n\n if (!reorderMode) return null\n\n const allRows = table.getRowModel().rows\n const currentIndex = allRows.findIndex(r => r.id === row.id)\n const isFirst = currentIndex === 0\n const isLast = currentIndex === allRows.length - 1\n\n return (\n <ReorderButtons\n id={row.original.id as number}\n isFirst={isFirst}\n isLast={isLast}\n onMoveRow={onMoveRow}\n />\n )\n },\n enableSorting: false,\n enableHiding: false,\n size: 80\n }`\n\n // --- Edit button ---\n let editButton = ''\n if (hasEdit) {\n editButton = ` <Button variant=\"outline\" className=\"size-8\" asChild>\n <Link href={\\`/cms/${schema.name}/\\${row.original.id}/edit\\`}>\n <Edit className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Edit ${singular} {${titleFallback}}</span>\n </Link>\n </Button>`\n }\n\n // --- Actions column ---\n const actionsColumn = ` {\n id: 'actions',\n header: () => <div className=\"text-right\">Actions</div>,\n cell: ({ row }) => (\n <div className=\"flex justify-end items-center gap-2\">\n${editButton}\n${hasDelete ? ' <DeleteAction id={row.original.id as number} />' : ''}\n </div>\n )\n }`\n\n // --- Truncate helper ---\n const truncateHelper = needsTruncate\n ? generateTruncateHelper()\n : ''\n\n // --- Assemble file ---\n const content = `'use client'\n\nimport type { ColumnDef } from '@tanstack/react-table'\n${needsReactQueryClient ? \"import { useQueryClient } from '@tanstack/react-query'\" : ''}\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'\nimport Link from 'next/link'\nimport * as React from 'react'\n${needsToast ? \"import { toast } from 'sonner'\" : ''}\n${uiImports.join('\\n')}\n${actionImports.length > 0 ? `import { ${actionImports.join(', ')} } from '@cms/actions/${schema.name}'` : ''}\nimport type { ${Singular}Data } from '@cms/actions/${schema.name}'\n${customImports.join('\\n')}\n${truncateHelper}${deleteHandler}${reorderHandler}\nexport const columns: ColumnDef<${Singular}Data>[] = [\n${reorderColumn},\n${firstColDef}${restColDefs ? `,\\n${restColDefs}` : ''},\n${actionsColumn}\n]\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(columnsFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'columns.tsx')]\n }\n}\n","/**\n * Column definition generators for TanStack Table columns\n */\n\nimport type { SchemaColumn, SchemaField } from '../../types.js'\n\n// ============================================================================\n// Column Helpers\n// ============================================================================\n\nexport function isSortableColumn(column: SchemaColumn): boolean {\n if (typeof column.sortable === 'boolean') return column.sortable\n const nonSortableTypes = ['image', 'avatar', 'link', 'custom']\n return !nonSortableTypes.includes(column.type)\n}\n\nexport function generateTitleFallback(fields: SchemaField[]): string {\n const fieldNames = new Set(fields.map((f) => f.name))\n const fallbacks: string[] = []\n if (fieldNames.has('title')) fallbacks.push('row.original.title')\n if (fieldNames.has('name')) fallbacks.push('row.original.name')\n fallbacks.push('row.original.id')\n fallbacks.push(\"''\")\n return fallbacks.join(' || ')\n}\n\n// ============================================================================\n// Cell Renderers\n// ============================================================================\n\nexport function generateColumnDef(column: SchemaColumn, fields: SchemaField[]): string {\n const sortable = isSortableColumn(column)\n const headerDef = sortable\n ? `header: ({ column }) => {\n const sortDirection = column.getIsSorted()\n const sortLabel = sortDirection === 'asc'\n ? 'sorted ascending'\n : sortDirection === 'desc'\n ? 'sorted descending'\n : 'not sorted'\n\n return (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n aria-label={\\`Sort by ${column.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${column.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n }`\n : `header: '${column.header}'`\n\n const titleFallback = generateTitleFallback(fields)\n let cellDef = ''\n\n switch (column.type) {\n case 'image':\n cellDef = `cell: ({ row }) => {\n const imageUrl = row.getValue('${column.accessorKey}') ?? ''\n const title = ${titleFallback}\n return (\n <Avatar className=\"size-10 border\">\n <AvatarImage\n src={imageUrl}\n alt={title ? \\`${column.header} image for \\${title}\\` : '${column.header} image'}\n />\n <AvatarFallback>\n {String(title || imageUrl).substring(0, 2).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n )\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return (\n <Badge variant=\"outline\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </Badge>\n )\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = new Date(row.getValue('${column.accessorKey}'))\n return (\n <div className=\"text-sm\">\n {date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric'\n })}\n </div>\n )\n }`\n break\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${column.accessorKey}') as string\n return <div className=\"text-sm font-medium\">{email}</div>\n }`\n break\n case 'number':\n if (column.format === 'currency') {\n cellDef = `cell: ({ row }) => {\n const amount = row.getValue('${column.accessorKey}') as number\n return (\n <div className=\"text-sm font-medium\">\n {new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount)}\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as number\n return <div className=\"text-sm\">{value}</div>\n }`\n }\n break\n case 'boolean':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as boolean\n return (\n <Badge variant={value ? 'outline' : 'secondary'}>\n {value ? 'Yes' : 'No'}\n </Badge>\n )\n }`\n break\n case 'link':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as string\n if (!value) return <div className=\"text-muted-foreground\">\\u2014</div>\n return (\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300\"\n title={value}\n >\n {truncateStr(value, 50)}\n </a>\n )\n }`\n break\n case 'custom':\n if (column.component) {\n cellDef = `cell: ({ row }) => {\n return <${column.component} data={row.original} />\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return <div>{value === null || value === undefined ? 'Unavailable' : String(value)}</div>\n }`\n }\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return <div>{value === null || value === undefined ? 'Unavailable' : String(value)}</div>\n }`\n break\n }\n\n return ` {\n accessorKey: '${column.accessorKey}',\n ${headerDef},\n ${cellDef}\n }`\n}\n\nexport function generateFirstColumnDef(\n column: SchemaColumn,\n fields: SchemaField[],\n schemaName: string\n): string {\n const sortable = isSortableColumn(column)\n const headerDef = sortable\n ? `header: ({ table, column }) => {\n const sortDirection = column.getIsSorted()\n const sortLabel = sortDirection === 'asc'\n ? 'sorted ascending'\n : sortDirection === 'desc'\n ? 'sorted descending'\n : 'not sorted'\n\n return (\n <div className=\"flex items-center gap-4\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n aria-label={\\`Sort by ${column.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${column.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n </div>\n )\n }`\n : `header: ({ table }) => (\n <div className=\"flex items-center gap-4\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n <span>${column.header}</span>\n </div>\n )`\n\n const titleFallback = generateTitleFallback(fields)\n const linkBase = `/cms/${schemaName}`\n let cellDef = ''\n\n switch (column.type) {\n case 'image':\n cellDef = `cell: ({ row }) => {\n const imageUrl = row.original.${column.accessorKey} as string\n const title = ${titleFallback}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Avatar className=\"size-10 border\">\n <AvatarImage\n src={imageUrl}\n alt={title ? \\`${column.header} image for \\${title}\\` : '${column.header} image'}\n />\n <AvatarFallback>\n {String(title || imageUrl).substring(0, 2).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Badge variant=\"outline\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </Badge>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = new Date(row.original.${column.accessorKey})\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm\">\n {date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric'\n })}\n </div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.original.${column.accessorKey} as string\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"text-sm font-medium truncate\">{email}</span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'number':\n if (column.format === 'currency') {\n cellDef = `cell: ({ row }) => {\n const amount = row.original.${column.accessorKey} as number\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm font-medium\">\n {new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD'\n }).format(amount)}\n </div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as number\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm\">{value}</div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n }\n break\n case 'boolean':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as boolean\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Badge variant={value ? 'outline' : 'secondary'}>\n {value ? 'Yes' : 'No'}\n </Badge>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'custom':\n if (column.component) {\n cellDef = `cell: ({ row }) => {\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <${column.component} data={row.original} />\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"truncate\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n }\n break\n case 'link':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as string\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity max-w-[250px]\">\n {value ? (\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300 truncate block\"\n title={value}\n onClick={(e) => e.stopPropagation()}\n >\n {truncateStr(value, 50)}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">\\u2014</span>\n )}\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"truncate\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n }\n\n return ` {\n id: 'select',\n accessorKey: '${column.accessorKey}',\n ${headerDef},\n ${cellDef},\n enableSorting: ${sortable ? 'true' : 'false'},\n enableHiding: false\n }`\n}\n","/**\n * Template strings for inline column action components:\n * DeleteAction, ReorderButtons, and truncateStr helper\n */\n\n// ============================================================================\n// Delete Action Component Template\n// ============================================================================\n\nexport function generateDeleteActionTemplate(params: {\n Singular: string\n singular: string\n plural: string\n}): string {\n const { Singular, singular, plural } = params\n\n return `\nfunction DeleteAction({ id }: { id: number }) {\n const [open, setOpen] = React.useState(false)\n const [isPending, startTransition] = React.useTransition()\n const queryClient = useQueryClient()\n\n const handleDelete = () => {\n startTransition(async () => {\n try {\n const result = await delete${Singular}(id)\n\n if (result.success) {\n toast.success('${Singular} deleted successfully')\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${singular}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n\n return (\n <AlertDialog open={open} onOpenChange={setOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" className=\"size-8\" aria-label={\\`Delete ${singular} \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete ${singular}</span>\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete this ${singular}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault()\n handleDelete()\n }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n`\n}\n\n// ============================================================================\n// Reorder Buttons Component Template\n// ============================================================================\n\nexport function generateReorderButtonsTemplate(): string {\n return `\nfunction ReorderButtons({\n id,\n isFirst,\n isLast,\n onMoveRow\n}: {\n id: number\n isFirst: boolean\n isLast: boolean\n onMoveRow?: (id: number, direction: 'up' | 'down') => void\n}) {\n if (!onMoveRow) return null\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => onMoveRow(id, 'up')}\n disabled={isFirst}\n aria-label=\"Move up\"\n className=\"size-7\"\n >\n <ChevronUp className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => onMoveRow(id, 'down')}\n disabled={isLast}\n aria-label=\"Move down\"\n className=\"size-7\"\n >\n <ChevronDown className=\"size-4\" />\n </Button>\n </div>\n )\n}\n`\n}\n\n// ============================================================================\n// Truncate Helper Template\n// ============================================================================\n\nexport function generateTruncateHelper(): string {\n return `\nfunction truncateStr(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return str.slice(0, maxLength) + '...'\n}\n`\n}\n","/**\n * Custom cell component generator — creates stub cell components for custom column types\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\n\nexport function createCustomCellComponent(\n schema: Schema,\n componentName: string,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions\n): void {\n const cellsDir = path.join(cwd, pagesDir, schema.name, 'cells')\n const componentFilePath = path.join(cellsDir, `${componentName}.tsx`)\n\n if (fs.existsSync(componentFilePath) && !options.force) return\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n const content = `import type { ${Singular}Data } from '@cms/actions/${schema.name}'\n\ninterface ${componentName}Props {\n data: ${Singular}Data\n}\n\nexport function ${componentName}({ data }: ${componentName}Props) {\n return (\n <div>\n {JSON.stringify(data)}\n </div>\n )\n}\n`\n\n if (!fs.existsSync(cellsDir)) {\n fs.mkdirSync(cellsDir, { recursive: true })\n }\n fs.writeFileSync(componentFilePath, content, 'utf-8')\n}\n","/**\n * Generator 9: Create page — (authenticated)/<n>/new/page.tsx\n * Generates server page component for creating a new entity\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, singularizeLabel, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface CreatePageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate create page component for adding a new entity\n */\nexport function generateCreatePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): CreatePageGeneratorResult {\n const newDir = path.join(cwd, pagesDir, schema.name, 'new')\n const pageFilePath = path.join(newDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const singLabel = singularizeLabel(schema.label)\n const kebabName = toKebabCase(schema.name)\n\n const content = `import { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { connection } from 'next/server'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { ${Singular}Form } from '../${kebabName}-form'\n\nexport default async function Create${Singular}Page() {\n await connection()\n\n return (\n <>\n <PageHeader title=\"Create ${singLabel}\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/${schema.name}\"><ChevronLeft /></Link></Button>} />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form key={Date.now()} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(newDir)) {\n fs.mkdirSync(newDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'new', 'page.tsx')]\n }\n}\n","/**\n * Generator 1: Database schema — append table to cms/db/schema.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../core/constants.js'\nimport { flattenFields, getManyToManyFields } from '../core/field-helpers/index.js'\nimport { toDrizzleType } from '../core/type-mappers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize } from '../utils/string.js'\n\n// ============================================================================\n// Field Modifiers\n// ============================================================================\n\nfunction getFieldModifiers(field: SchemaField, needsSql: { value: boolean }): string {\n const modifiers: string[] = []\n\n if (field.primaryKey) {\n modifiers.push('.primaryKey()')\n }\n\n const isDateField = field.type === 'date' || field.type === 'timestamp'\n const hasValidDefault =\n field.default !== undefined && field.default !== null && !(isDateField && field.default === '')\n\n if (hasValidDefault) {\n if (typeof field.default === 'string') {\n modifiers.push(`.default('${field.default}')`)\n } else {\n modifiers.push(`.default(${field.default})`)\n }\n }\n\n if (field.name === 'createdAt' || field.name === 'updatedAt') {\n modifiers.push('.default(sql`CURRENT_TIMESTAMP`)')\n needsSql.value = true\n }\n\n if (field.required || field.primaryKey) {\n modifiers.push('.notNull()')\n }\n\n return modifiers.join('')\n}\n\n// ============================================================================\n// Table Generation\n// ============================================================================\n\nfunction generateTableDefinition(\n schema: Schema,\n requiredImports: Set<string>,\n needsSql: { value: boolean }\n): string {\n const tableName = toPascalCase(schema.name)\n const variableName = toCamelCase(schema.name)\n\n requiredImports.add('pgTable')\n\n // Flatten fields, exclude M2M relationships (handled via junction tables)\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true) && !isLayoutField(f.type)\n )\n\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = dbFields.some((f) => f.name === 'published')\n\n const fieldDefs = dbFields\n .map((field) => {\n const drizzleType = toDrizzleType(field, requiredImports)\n const modifiers = getFieldModifiers(field, needsSql)\n const line = ` ${field.name}: ${drizzleType}${modifiers}`\n\n if ((field.type === 'richtext' || field.type === 'markdown') && field.output === 'html') {\n const snakeName = field.name.replace(/([A-Z])/g, '_$1').toLowerCase()\n requiredImports.add('text')\n return `${line},\\n ${field.name}Html: text('${snakeName}_html')`\n }\n\n return line\n })\n .join(',\\n')\n\n // Auto-add published field for draft mode\n let publishedField = ''\n if (hasDraftMode && !hasPublishedField) {\n requiredImports.add('boolean')\n publishedField = `,\\n published: boolean().notNull().default(false)`\n }\n\n // Auto-add timestamps\n const hasCreatedAt = dbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = dbFields.some((f) => f.name === 'updatedAt')\n let timestampFields = ''\n if (!hasCreatedAt || !hasUpdatedAt) {\n requiredImports.add('timestamp')\n needsSql.value = true\n }\n if (!hasCreatedAt) {\n timestampFields += `,\\n createdAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()`\n }\n if (!hasUpdatedAt) {\n timestampFields += `,\\n updatedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()`\n }\n\n // Auto-add sortOrder for drag-and-drop reordering (skip for single schemas)\n const isSingle = schema.type === 'single'\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n let sortOrderField = ''\n if (!isSingle && !hasSortOrder) {\n requiredImports.add('integer')\n sortOrderField = `,\\n sortOrder: integer().notNull().default(0)`\n }\n\n return `\\nexport const ${variableName} = pgTable(\\n '${tableName}',\\n {\\n${fieldDefs}${publishedField}${timestampFields}${sortOrderField}\\n }\\n)\\n`\n}\n\nfunction generateJunctionTable(\n schemaName: string,\n field: SchemaField,\n requiredImports: Set<string>\n): string {\n const singularSchema = singularize(schemaName)\n const singularRelation = singularize(field.relationship || '')\n const junctionName = `${singularSchema}${toPascalCase(field.relationship || '')}`\n const junctionPascal = toPascalCase(junctionName)\n const schemaIdCol = `${singularSchema}Id`\n const relationIdCol = `${singularRelation}Id`\n const schemaTableRef = toCamelCase(schemaName)\n const relationTableRef = toCamelCase(field.relationship || '')\n\n requiredImports.add('pgTable')\n requiredImports.add('integer')\n requiredImports.add('primaryKey')\n\n return `\\nexport const ${toCamelCase(junctionName)} = pgTable(\\n '${junctionPascal}',\\n {\\n ${schemaIdCol}: integer().notNull().references(() => ${schemaTableRef}.id, { onDelete: 'cascade' }),\\n ${relationIdCol}: integer().notNull().references(() => ${relationTableRef}.id, { onDelete: 'cascade' })\\n },\\n (table) => [primaryKey({ columns: [table.${schemaIdCol}, table.${relationIdCol}] })]\\n)\\n`\n}\n\n// ============================================================================\n// Import Merging\n// ============================================================================\n\nfunction mergeImports(content: string, requiredImports: Set<string>, needsSql: boolean): string {\n const pgCoreMatch = content.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/)\n\n // Use regex to detect sql import — handles single/double quotes, extra whitespace, semicolons\n const drizzleOrmMatch = content.match(/import\\s*\\{([^}]*)\\}\\s*from\\s*['\"]drizzle-orm['\"]/)\n const existingDrizzleOrmImports = new Set<string>()\n if (drizzleOrmMatch) {\n drizzleOrmMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n .forEach((i) => {\n existingDrizzleOrmImports.add(i)\n })\n }\n const hasSqlImport = existingDrizzleOrmImports.has('sql')\n\n // Collect existing pg-core imports\n const existing = new Set<string>()\n if (pgCoreMatch) {\n pgCoreMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n .forEach((i) => {\n existing.add(i)\n })\n }\n\n const merged = new Set([...existing, ...requiredImports])\n const sorted = Array.from(merged).sort()\n const newImport = `import {\\n ${sorted.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n\n let updated = content\n\n if (pgCoreMatch) {\n updated = updated.replace(/import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/, newImport)\n } else if (drizzleOrmMatch) {\n updated = updated.replace(\n /import\\s*\\{[^}]*\\}\\s*from\\s*['\"]drizzle-orm['\"]/,\n (match) => `${match}\\n${newImport}`\n )\n } else {\n updated = `${newImport}\\n${updated}`\n }\n\n if (needsSql && !hasSqlImport) {\n if (drizzleOrmMatch) {\n // Add sql to existing drizzle-orm import\n existingDrizzleOrmImports.add('sql')\n const sortedOrm = Array.from(existingDrizzleOrmImports).sort()\n updated = updated.replace(\n /import\\s*\\{[^}]*\\}\\s*from\\s*['\"]drizzle-orm['\"]/,\n `import { ${sortedOrm.join(', ')} } from 'drizzle-orm'`\n )\n } else {\n updated = `import { sql } from 'drizzle-orm'\\n${updated}`\n }\n }\n\n return updated\n}\n\n// ============================================================================\n// Table End Finder (for --force replacement)\n// ============================================================================\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n return i + 1\n }\n }\n\n return content.length\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface DatabaseGeneratorResult {\n files: string[]\n tableName: string\n junctionTables: string[]\n}\n\n/**\n * Generate database schema for an entity — appends to cms/db/schema.ts\n */\nexport function generateDatabase(\n schema: Schema,\n cwd: string,\n schemaDir: string,\n options: GeneratorOptions = {}\n): DatabaseGeneratorResult {\n const schemaFilePath = path.join(cwd, schemaDir)\n const files: string[] = []\n\n // Read existing schema.ts\n let content = ''\n if (fs.existsSync(schemaFilePath)) {\n content = fs.readFileSync(schemaFilePath, 'utf-8')\n }\n\n const variableName = toCamelCase(schema.name)\n\n // Check for existing table\n if (content.includes(`export const ${variableName} =`) && !options.force) {\n return {\n files: [],\n tableName: variableName,\n junctionTables: []\n }\n }\n\n const requiredImports = new Set<string>()\n const needsSql = { value: false }\n\n // Generate main table\n const tableDef = generateTableDefinition(schema, requiredImports, needsSql)\n\n // Generate junction tables for M2M\n const m2mFields = getManyToManyFields(schema.fields)\n const junctionDefs = m2mFields.map((f) => generateJunctionTable(schema.name, f, requiredImports))\n const junctionNames = m2mFields.map((f) => {\n const s = singularize(schema.name)\n return toCamelCase(`${s}${toPascalCase(f.relationship || '')}`)\n })\n\n let updated = content\n\n if (options.force && content.includes(`export const ${variableName} =`)) {\n // Replace existing table definition\n const start = content.indexOf(`export const ${variableName} =`)\n const end = findTableEnd(content, start)\n updated = content.slice(0, start) + tableDef.trim() + content.slice(end)\n } else {\n // Append new table\n updated = `${updated.trimEnd()}\\n${tableDef}`\n }\n\n // Handle junction tables\n for (let i = 0; i < m2mFields.length; i++) {\n const jName = junctionNames[i]\n if (options.force && updated.includes(`export const ${jName} =`)) {\n const start = updated.indexOf(`export const ${jName} =`)\n const end = findTableEnd(updated, start)\n updated = updated.slice(0, start) + junctionDefs[i].trim() + updated.slice(end)\n } else if (!updated.includes(`export const ${jName} =`)) {\n updated = `${updated.trimEnd()}\\n${junctionDefs[i]}`\n }\n }\n\n // Merge imports\n updated = mergeImports(updated, requiredImports, needsSql.value)\n\n // Write\n const dir = path.dirname(schemaFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(schemaFilePath, updated, 'utf-8')\n files.push(schemaDir)\n\n return {\n files,\n tableName: variableName,\n junctionTables: junctionNames\n }\n}\n","/**\n * Generator 10: Edit page — (authenticated)/<n>/[id]/edit/page.tsx\n * Generates server page component for editing an existing entity\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface EditPageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate edit page component for updating an existing entity\n */\nexport function generateEditPage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): EditPageGeneratorResult {\n const editDir = path.join(cwd, pagesDir, schema.name, '[id]', 'edit')\n const pageFilePath = path.join(editDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const camelSingular = toCamelCase(singular)\n const kebabName = toKebabCase(schema.name)\n\n const content = `import { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { connection } from 'next/server'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { get${Singular}ById } from '@cms/actions/${schema.name}'\nimport { ${Singular}Form } from '../../${kebabName}-form'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Edit${Singular}Page({ params }: PageProps) {\n const { id } = await params\n await connection()\n const ${camelSingular} = await get${Singular}ById(Number.parseInt(id, 10))\n\n if (!${camelSingular}) {\n notFound()\n }\n\n return (\n <>\n <PageHeader title=\"Edit ${Singular}\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/${schema.name}\"><ChevronLeft /></Link></Button>} />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form key={${camelSingular}.id} initialData={${camelSingular}} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(editDir)) {\n fs.mkdirSync(editDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, '[id]', 'edit', 'page.tsx')]\n }\n}\n","/**\n * Entity form generator — create/edit form with Zod validation, React Hook Form, and mutations\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields, hasFieldType, hasIconUsage } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, singularize, pluralize } from '../../utils/string.js'\nimport { generateFieldJSX } from './field-jsx.js'\nimport {\n type FormGeneratorResult,\n collectRelationshipFields,\n buildZodFields,\n buildDefaultValues,\n buildUiImports\n} from './form-shared.js'\n\nexport function generateForm(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): FormGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const formFilePath = path.join(entityDir, `${schema.name}-form.tsx`)\n\n if (fs.existsSync(formFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n\n // Analyze fields\n const allFormFields = schema.fields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n const flatFields = flattenFields(allFormFields)\n const hasDraft = schema.actions?.draft === true\n\n // Collect tab field names\n const tabFieldNames = new Set<string>()\n for (const f of schema.fields) {\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) for (const tf of tab.fields) tabFieldNames.add(tf.name)\n }\n }\n }\n\n // Check what components are needed\n const hasBoolean = hasFieldType(schema.fields, 'boolean')\n const hasImage = hasFieldType(schema.fields, 'image')\n const hasVideo = hasFieldType(schema.fields, 'video')\n const hasMedia = hasFieldType(schema.fields, 'media')\n const hasIcon = hasFieldType(schema.fields, 'icon')\n const hasIconPostfix = hasIconUsage(schema.fields)\n const hasDate = hasFieldType(schema.fields, 'date')\n const hasSelect = hasFieldType(schema.fields, 'select')\n const hasMarkdown = hasFieldType(schema.fields, 'markdown')\n const hasRichtext = hasFieldType(schema.fields, 'richtext')\n const hasTextarea = hasFieldType(schema.fields, 'text')\n const hasSeparator = hasFieldType(schema.fields, 'separator')\n const hasRelationship = hasFieldType(schema.fields, 'relationship')\n const hasTabsField = schema.fields.some((f) => f.type === 'tabs')\n const tabsField = schema.fields.find((f) => f.type === 'tabs')\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n const mainRelFields = collectRelationshipFields(schema.fields, tabFieldNames)\n\n // Collect list fields with nested fields (need useFieldArray hooks)\n const listFieldsWithNested: SchemaField[] = []\n function collectListFields(fields: SchemaField[]): void {\n for (const f of fields) {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n listFieldsWithNested.push(f)\n }\n if (f.type === 'group' && f.fields) collectListFields(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collectListFields(tab.fields)\n }\n }\n }\n }\n collectListFields(allFormFields)\n const hasList = hasFieldType(schema.fields, 'list')\n const hasNestedList = listFieldsWithNested.length > 0\n // Simple list uses DynamicListField; nested list uses useFieldArray + Accordion\n const hasSimpleList =\n hasList && flatFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n\n // Build Zod schema\n const zodFields = buildZodFields(flatFields)\n\n // Build default values\n const defaultValues = buildDefaultValues(flatFields)\n\n // Build form fields JSX\n const formFieldsJSX = allFormFields\n .filter((f) => !(hasDraft && f.name === 'published'))\n .map((f) => {\n if (f.type === 'tabs' && f.tabs) {\n const tabsList = f.tabs\n .map((t) => ` <TabsTrigger value=\"${t.name}\">${t.label}</TabsTrigger>`)\n .join('\\n')\n const tabsContent = f.tabs\n .map((t) => {\n const tabFields = (t.fields || [])\n .map((tf) => generateFieldJSX(tf, ' '))\n .join('\\n')\n return ` <TabsContent value=\"${t.name}\" className=\"space-y-6 p-6 rounded-2xl border bg-card\">\n${tabFields}\n </TabsContent>`\n })\n .join('\\n')\n return ` <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n </Tabs>`\n }\n if (tabFieldNames.has(f.name)) return ''\n return generateFieldJSX(f)\n })\n .filter(Boolean)\n .join('\\n')\n\n // --- Build imports ---\n const uiImports = buildUiImports({\n hasBoolean,\n hasTextarea,\n hasImage,\n hasVideo,\n hasMedia,\n hasIcon,\n hasIconPostfix,\n hasDate,\n hasMarkdown,\n hasRichtext,\n hasSeparator,\n hasSelect,\n hasTabsField,\n hasRelationship,\n hasSimpleList,\n hasNestedList\n })\n\n // Lucide icons\n const lucideIcons: string[] = []\n if (hasRelationship) lucideIcons.push('Check', 'ChevronsUpDown')\n if (hasNestedList) {\n if (!lucideIcons.includes('Plus')) lucideIcons.push('Plus')\n if (!lucideIcons.includes('X')) lucideIcons.push('X')\n }\n\n // Relationship hooks\n const relHookImports = mainRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relPlural} } from '@cms/hooks/use-${f.relationship}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // Relationship state\n const relState = mainRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return ` const [${f.name}Open, set${toPascalCase(f.name)}Open] = React.useState(false)\n const { data: ${f.relationship}Data } = use${relPlural}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // List field array hooks\n const fieldArrayHooks = listFieldsWithNested\n .map((field) => {\n const pascalFieldName = toPascalCase(field.name)\n return ` const [${field.name}Expanded, set${pascalFieldName}Expanded] = React.useState<string | undefined>(undefined)\n const ${field.name}FieldArray = useFieldArray({\n control: form.control,\n name: '${field.name}'\n })`\n })\n .join('\\n')\n\n const needsReact = mainRelFields.length > 0 || hasNestedList\n\n // --- Assemble file ---\n const content = `'use client'\n${needsReact ? \"\\nimport * as React from 'react'\" : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideIcons.length > 0 ? `\\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\nimport { useRouter } from 'next/navigation'\nimport {${hasNestedList ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod/v3'${hasTabsField ? \"\\nimport { useQueryState } from 'nuqs'\" : ''}${hasRelationship ? \"\\nimport { cn } from '@cms/utils/cn'\" : ''}\n${relHookImports ? `${relHookImports}\\n` : ''}${uiImports.join('\\n')}\nimport type {\n Create${Singular}Input,\n ${Singular}Data,\n Update${Singular}Input\n} from '@cms/actions/${schema.name}'\nimport { create${Singular}, update${Singular} } from '@cms/actions/${schema.name}'\n\nconst formSchema = z.object({\n${zodFields}\n})\n\nexport type FormValues = z.infer<typeof formSchema>\n\ninterface ${Singular}FormProps {\n initialData?: ${Singular}Data\n}\n\nexport function ${Singular}Form({ initialData }: ${Singular}FormProps) {\n const router = useRouter()\n const queryClient = useQueryClient()${hasTabsField ? `\\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${firstTabName}' })` : ''}${relState ? `\\n${relState}` : ''}\n\n const createMutation = useMutation({\n mutationFn: (data: Create${Singular}Input) => create${Singular}(data),\n onSuccess: async () => {\n toast.success('${Singular} created successfully')\n await queryClient.invalidateQueries({ queryKey: ['${plural}'] })\n router.push('/cms/${schema.name}')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to create ${singular}')\n }\n })\n\n const updateMutation = useMutation({\n mutationFn: (data: Update${Singular}Input) => update${Singular}(data),\n onSuccess: () => {\n toast.success('${Singular} updated successfully')\n queryClient.invalidateQueries({ queryKey: ['${plural}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update ${singular}')\n }\n })\n\n const isPending = createMutation.isPending || updateMutation.isPending\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaultValues}\n }\n })\n${fieldArrayHooks ? `\\n${fieldArrayHooks}\\n` : ''}\n function onSubmit(values: FormValues${hasDraft ? ', publishedValue: boolean = false' : ''}) {\n const cleanedValues = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [key, value === undefined ? '' : value])\n ) as FormValues\n\n if (initialData) {\n updateMutation.mutate({\n id: initialData.id as number,\n ...cleanedValues${hasDraft ? ',\\n published: publishedValue' : ''}\n })\n } else {\n const { id: _id, ...createValues } = cleanedValues\n createMutation.mutate({\n ...createValues${hasDraft ? ',\\n published: publishedValue' : ''}\n } as Create${Singular}Input)\n }\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-form\" onSubmit={form.handleSubmit((values) => onSubmit(values${hasDraft ? ', false' : ''}), (errors) => {\n console.error('Form validation errors:', errors)\n const firstError = Object.values(errors)[0]\n if (firstError?.message) {\n toast.error(String(firstError.message))\n } else {\n toast.error('Please fix the form errors before submitting')\n }\n })} className=\"space-y-6\">\n <div className=\"space-y-6 p-6 rounded-2xl border bg-card\">\n${formFieldsJSX}\n </div>\n\n <div className=\"flex items-center fixed bottom-0 md:left-[calc(var(--sidebar-width))] w-screen md:w-[calc(100svw-var(--sidebar-width)-4px)] right-0 bg-secondary border-t\">\n <div className=\"flex mx-auto py-4 w-full max-w-5xl items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push('/cms/${schema.name}')}\n disabled={isPending}\n size=\"lg\"\n >\n Cancel\n </Button>\n${\n hasDraft\n ? ` <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isPending ? 'Saving...' : 'Save as Draft'}\n </Button>\n <Button\n type=\"button\"\n variant=\"default\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, true))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isPending ? 'Publishing...' : initialData ? 'Update & Publish' : 'Publish'}\n </Button>`\n : ` <Button type=\"submit\" disabled={isPending} size=\"lg\">\n {isPending ? 'Saving...' : initialData ? 'Update' : 'Create'}\n </Button>`\n}\n </div>\n </div>\n </form>\n </Form>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, `${schema.name}-form.tsx`)]\n }\n}\n","/**\n * Zod schema generation helpers for entity/single forms\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\nexport function getFormFieldType(field: SchemaField): string {\n switch (field.type) {\n case 'boolean':\n return 'checkbox'\n case 'text':\n return 'textarea'\n case 'markdown':\n return 'markdown'\n case 'richtext':\n return 'richtext'\n case 'number':\n case 'decimal':\n return 'number'\n case 'date':\n return 'date'\n case 'time':\n return 'time'\n case 'timestamp':\n return 'datetime-local'\n default:\n return 'text'\n }\n}\n\nexport function getZodType(field: SchemaField): string {\n const label = field.label || field.name\n\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return field.required\n ? `z.number({ message: '${label} is required' })`\n : 'z.number().optional()'\n case 'boolean':\n return 'z.boolean()'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext': {\n if (field.name.toLowerCase().includes('email')) {\n const base = field.required\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().email('Please enter a valid email address').optional()`\n return field.length ? `${base}.max(${field.length})` : base\n }\n const base = field.required ? `z.string().min(1, '${label} is required')` : 'z.string()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'date':\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n return `z.string().min(1, '${label} is required')`\n case 'timestamp':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'image':\n case 'video':\n case 'media': {\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const base = `z.string().min(1, 'Please upload ${label.toLowerCase()}').url('Please provide a valid URL')`\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nested = field.fields\n .flatMap((nf) => {\n const defs: string[] = []\n const zodType = getZodType(nf)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(nf.name)}: ${zodType}`\n if (!nf.required && !alreadyOptional) def += '.optional()'\n defs.push(def)\n if (nf.hasIcon)\n defs.push(` ${quotePropertyName(`${nf.name}Icon`)}: z.string().optional()`)\n return defs\n })\n .join(',\\n')\n const obj = `z.object({\\n${nested}\\n })`\n const arr = field.maxItems ? `z.array(${obj}).max(${field.maxItems})` : `z.array(${obj})`\n return field.required\n ? `${arr}.min(1, '${label} must have at least one item')`\n : `${arr}.optional()`\n }\n return field.required\n ? `z.array(z.string()).min(1, '${label} must have at least one item')`\n : 'z.array(z.string()).optional()'\n case 'select': {\n if (field.options && field.options.length > 0) {\n const values = field.options.map((o) => `'${o.value}'`).join(', ')\n const arr = `[${values}] as const`\n return field.required\n ? `z.string().min(1, '${label} is required').refine((val) => (${arr} as readonly string[]).includes(val), { message: 'Invalid ${label}' })`\n : `z.string().refine((val) => !val || (${arr} as readonly string[]).includes(val), { message: 'Invalid ${label}' }).optional()`\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'icon':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'relationship':\n if (field.multiple) {\n return field.required\n ? `z.array(z.number()).min(1, '${label} is required')`\n : 'z.array(z.number()).optional()'\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'group':\n if (field.fields && field.fields.length > 0) {\n const nested = field.fields\n .map((nf) => {\n const zodType = getZodType(nf)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(nf.name)}: ${zodType}`\n if (!nf.required && !alreadyOptional) def += '.optional()'\n return def\n })\n .join(',\\n')\n return field.required\n ? `z.object({\\n${nested}\\n })`\n : `z.object({\\n${nested}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n","/**\n * List/nested-list JSX generation for form fields\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\n\nexport function renderListField(field: SchemaField, indent: string, label: string): string {\n const listHintJSX = field.hint\n ? `${indent} <p className=\"text-[0.8rem] text-muted-foreground\">${field.hint}</p>`\n : ''\n\n // Simple string list — use DynamicListField\n if (!field.fields || field.fields.length === 0) {\n return `${indent}<DynamicListField\n${indent} name=\"${field.name}\"\n${indent} label=\"${label}\"\n${indent} disabled={isPending}${field.maxItems ? `\\n${indent} maxItems={${field.maxItems}}` : ''}\n${indent} placeholder=\"Enter value\"\n${indent}/>`\n }\n\n // Nested fields list — useFieldArray + Accordion\n const singularLabel = singularize(label)\n const pascalFieldName = toPascalCase(field.name)\n\n // Find title field for accordion header\n const stringTypes = ['string', 'varchar', 'text']\n const titleField =\n field.fields.find((f) => f.name === 'title' && stringTypes.includes(f.type)) ||\n field.fields.find((f) => f.name === 'name' && stringTypes.includes(f.type)) ||\n field.fields.find((f) => stringTypes.includes(f.type))\n const accordionTitle = titleField\n ? `{form.watch(\\`${field.name}.\\${index}.${titleField.name}\\`) || '${singularLabel} ' + (index + 1)}`\n : `${singularLabel} {index + 1}`\n\n // Generate nested field JSX\n const nestedFieldsJSX = field.fields\n .map((nf) => {\n const nestedLabel = nf.label || nf.name\n const nestedHint = nf.hint\n ? `\\n${indent} <FormDescription>${nf.hint}</FormDescription>`\n : ''\n if (nf.type === 'boolean') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox checked={formField.value} onCheckedChange={formField.onChange} disabled={isPending} />\n${indent} </FormControl>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'image') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={10} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'video') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <VideoUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={100} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'media') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <MediaUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={100} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n // Default: text input for nested fields\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input placeholder=\"Enter ${nestedLabel.toLowerCase()}\" disabled={isPending} {...formField} />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n })\n .join('\\n')\n\n return `${indent}<FormItem>\n${indent} {${field.name}FieldArray.fields.length === 0 && (\n${indent} <div className=\"text-sm text-muted-foreground rounded-lg border border-dashed p-6 text-center\">\n${indent} <p>No ${label.toLowerCase()} added yet.</p>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} className=\"mt-2\"\n${indent} onClick={() => {\n${indent} ${field.name}FieldArray.append({${field.fields.map((nf) => `${nf.name}: ${nf.type === 'boolean' ? 'false' : \"''\"}`).join(', ')}})\n${indent} set${pascalFieldName}Expanded(\\`item-\\${${field.name}FieldArray.fields.length + 1}\\`)\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className=\"size-3\" />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${indent} )}\n${indent} {${field.name}FieldArray.fields.length > 0 && (\n${indent} <div className=\"space-y-5\">\n${indent} <div className=\"flex items-center justify-between\">\n${indent} <Label className=\"text-base\">${label}</Label>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} ${field.name}FieldArray.append({${field.fields.map((nf) => `${nf.name}: ${nf.type === 'boolean' ? 'false' : \"''\"}`).join(', ')}})\n${indent} set${pascalFieldName}Expanded(\\`item-\\${${field.name}FieldArray.fields.length + 1}\\`)\n${indent} }}\n${indent} disabled={isPending${field.maxItems ? ` || ${field.name}FieldArray.fields.length >= ${field.maxItems}` : ''}}\n${indent} >\n${indent} <Plus className=\"size-3\" />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${listHintJSX ? `${listHintJSX}\\n` : ''}${indent} <Accordion\n${indent} type=\"single\"\n${indent} collapsible\n${indent} className=\"w-full gap-1 flex flex-col\"\n${indent} value={${field.name}Expanded}\n${indent} onValueChange={set${pascalFieldName}Expanded}\n${indent} >\n${indent} {${field.name}FieldArray.fields.map((item, index) => (\n${indent} <AccordionItem\n${indent} key={item.id}\n${indent} value={\\`item-\\${index + 1}\\`}\n${indent} className=\"p-0 border-none\"\n${indent} >\n${indent} <div className=\"space-y-5 rounded-lg border p-4 bg-secondary/50 [&_h3]:m-0 w-full\">\n${indent} <AccordionTrigger className=\"flex items-center p-0 justify-between w-full\">\n${indent} <h4 className=\"text-sm font-medium w-full\">\n${indent} ${accordionTitle}\n${indent} </h4>\n${indent} <Button\n${indent} asChild\n${indent} variant=\"ghost\"\n${indent} size=\"sm\"\n${indent} disabled={isPending}\n${indent} >\n${indent} <span\n${indent} role=\"button\"\n${indent} tabIndex={0}\n${indent} onClick={(e) => { e.stopPropagation(); ${field.name}FieldArray.remove(index); }}\n${indent} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); ${field.name}FieldArray.remove(index); } }}\n${indent} className=\"cursor-pointer\"\n${indent} >\n${indent} <X className=\"size-3\" />\n${indent} </span>\n${indent} </Button>\n${indent} </AccordionTrigger>\n${indent} <AccordionContent className=\"flex flex-col gap-4 px-1\">\n${indent} <Separator className=\"mt-2\" />\n${indent} <div className=\"space-y-5\">\n${nestedFieldsJSX}\n${indent} </div>\n${indent} </AccordionContent>\n${indent} </div>\n${indent} </AccordionItem>\n${indent} ))}\n${indent} </Accordion>\n${indent} </div>\n${indent} )}\n${indent}</FormItem>`\n}\n","/**\n * Form field JSX generation — dispatcher + per-type renderers\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\nimport { getFormFieldType } from './zod-schema.js'\nimport { renderListField } from './field-jsx-nested.js'\n\nexport interface FieldJSXOptions {\n skipLabel?: boolean\n}\n\nfunction generateIconPostfix(field: SchemaField, indent: string): string {\n const label = field.label || field.name\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}Icon\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label} Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} triggerPlaceholder=\"Select icon\"\n${indent} />\n${indent} </FormControl>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nexport function generateFieldJSX(field: SchemaField, indent = ' ', options?: FieldJSXOptions): string {\n if (field.hidden) return ''\n\n let mainJSX = generateFieldJSXCore(field, indent)\n if (!mainJSX) return ''\n\n if (options?.skipLabel) {\n mainJSX = mainJSX\n .split('\\n')\n .filter(line => !line.includes('<FormLabel>'))\n .join('\\n')\n }\n\n if (field.hasIcon) {\n return `${mainJSX}\\n${generateIconPostfix(field, indent)}`\n }\n\n return mainJSX\n}\n\nfunction generateFieldJSXCore(field: SchemaField, indent = ' '): string {\n const fieldType = getFormFieldType(field)\n const label = field.label || field.name\n const hintJSX = field.hint\n ? `${indent} <FormDescription>${field.hint}</FormDescription>`\n : ''\n\n if ((field.type === 'group' || field.type === 'section') && field.fields) return renderGroupField(field, indent, label)\n if (field.type === 'separator') return renderSeparatorField(field, indent)\n if (field.type === 'boolean') return renderBooleanField(field, indent, label, hintJSX)\n if (field.type === 'image') return renderImageField(field, indent, label, hintJSX)\n if (field.type === 'video') return renderVideoField(field, indent, label, hintJSX)\n if (field.type === 'media') return renderMediaField(field, indent, label, hintJSX)\n if (field.type === 'icon') return renderIconField(field, indent, label, hintJSX)\n if (field.type === 'date') return renderDateField(field, indent, label, hintJSX)\n if (field.type === 'select') return renderSelectField(field, indent, label, hintJSX)\n if (field.type === 'richtext') return renderRichtextField(field, indent, label, hintJSX)\n if (field.type === 'markdown') return renderMarkdownField(field, indent, label, hintJSX)\n if (field.type === 'text') return renderTextareaField(field, indent, label, hintJSX)\n if (field.type === 'relationship' && field.relationship)\n return renderRelationshipField(field, indent, label, hintJSX)\n if (field.type === 'list') return renderListField(field, indent, label)\n\n return renderDefaultField(field, indent, label, fieldType, hintJSX)\n}\n\nfunction renderGroupField(field: SchemaField, indent: string, label: string): string {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields!.map((nf) => generateFieldJSX(nf, `${indent} `)).join('\\n')\n const heading =\n label && label !== field.name\n ? `${indent}<h3 className=\"text-lg font-medium\">${label}</h3>\\n`\n : ''\n return `${indent}<div className=\"space-y-5\">\n${heading}${indent} <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n${indent} </div>\n${indent}</div>`\n}\n\nfunction renderSeparatorField(field: SchemaField, indent: string): string {\n if (field.label) {\n return `${indent}<div className=\"relative my-4\">\n${indent} <div className=\"absolute inset-0 flex items-center\">\n${indent} <Separator className=\"w-full\" />\n${indent} </div>\n${indent} <div className=\"relative flex justify-center text-xs uppercase\">\n${indent} <span className=\"bg-background px-2 text-muted-foreground\">${field.label}</span>\n${indent} </div>\n${indent}</div>`\n }\n return `${indent}<Separator className=\"my-4\" />`\n}\n\nfunction renderBooleanField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={formField.value}\n${indent} onCheckedChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${label}</FormLabel>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} </div>\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderImageField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={10}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderVideoField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <VideoUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={100}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderMediaField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <MediaUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={100}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderIconField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} triggerPlaceholder=\"Select ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderDateField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <DatePicker\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} placeholder=\"Select ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderSelectField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n const options = field.options || []\n const optionsJSX = options\n .map(\n (o) =>\n `${indent} <SelectItem key=\"${o.value}\" value=\"${o.value}\">${o.label}</SelectItem>`\n )\n .join('\\n')\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Select\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} >\n${indent} <SelectTrigger>\n${indent} <SelectValue placeholder=\"Select ${label.toLowerCase()}\" />\n${indent} </SelectTrigger>\n${indent} <SelectContent>\n${optionsJSX}\n${indent} </SelectContent>\n${indent} </Select>\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderRichtextField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <RichTextEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} className=\"min-h-[300px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderMarkdownField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <MarkdownEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} componentSnippets={{}}\n${indent} className=\"min-h-[300px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderTextareaField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} className=\"min-h-[100px]\"\n${indent} disabled={isPending}\n${indent} {...formField}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n const relName = field.relationship!\n const relSingular = singularize(relName)\n const relPascal = toPascalCase(relSingular)\n const displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n const dataArray = `${relName}Data?.${relName}`\n\n if (field.multiple) {\n return renderMultiRelationshipField(field, indent, label, hintJSX, displayField, dataArray, relSingular)\n }\n\n return renderSingleRelationshipField(field, indent, label, hintJSX, displayField, dataArray, relSingular)\n}\n\nfunction renderMultiRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string,\n displayField: string,\n dataArray: string,\n relSingular: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <Popover open={${field.name}Open} onOpenChange={set${toPascalCase(field.name)}Open}>\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\"w-full justify-between\", (!formField.value || formField.value.length === 0) && \"text-muted-foreground\")}\n${indent} disabled={isPending}\n${indent} >\n${indent} {(formField.value?.length ?? 0) > 0\n${indent} ? \\`\\${formField.value!.length} selected\\`\n${indent} : \"Select ${label.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n${indent} </Button>\n${indent} </FormControl>\n${indent} </PopoverTrigger>\n${indent} <PopoverContent className=\"w-full p-0\" align=\"start\">\n${indent} <Command>\n${indent} <CommandInput placeholder=\"Search ${label.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${relSingular} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.filter((item) => item.id !== null).map((item) => {\n${indent} const displayName = ${displayField}\n${indent} const isSelected = formField.value?.includes(item.id as number) || false\n${indent} return (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={displayName}\n${indent} onSelect={() => {\n${indent} const current = formField.value || []\n${indent} formField.onChange(isSelected\n${indent} ? current.filter((id: number) => id !== item.id)\n${indent} : [...current, item.id as number])\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 size-4\", isSelected ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {displayName}\n${indent} </CommandItem>\n${indent} )\n${indent} })}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderSingleRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string,\n displayField: string,\n dataArray: string,\n relSingular: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <Popover open={${field.name}Open} onOpenChange={set${toPascalCase(field.name)}Open}>\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\"w-full justify-between\", !formField.value && \"text-muted-foreground\")}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value\n${indent} ? (() => {\n${indent} const item = ${dataArray}?.find((item) => item.id !== null && String(item.id) === formField.value)\n${indent} return item ? (${displayField}) : \"Select ${label.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${label.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n${indent} </Button>\n${indent} </FormControl>\n${indent} </PopoverTrigger>\n${indent} <PopoverContent className=\"w-full p-0\" align=\"start\">\n${indent} <Command>\n${indent} <CommandInput placeholder=\"Search ${label.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${relSingular} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.filter((item) => item.id !== null).map((item) => {\n${indent} const displayName = ${displayField}\n${indent} return (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={displayName}\n${indent} onSelect={() => {\n${indent} formField.onChange(String(item.id))\n${indent} set${toPascalCase(field.name)}Open(false)\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 size-4\", formField.value === String(item.id) ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {displayName}\n${indent} </CommandItem>\n${indent} )\n${indent} })}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderDefaultField(\n field: SchemaField,\n indent: string,\n label: string,\n fieldType: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${fieldType}\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} {...formField}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n","/**\n * Shared logic for entity and single form generators\n */\n\nimport { isLayoutField } from '../../core/constants.js'\nimport type { SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\nimport { getZodType } from './zod-schema.js'\n\nexport interface FormGeneratorResult {\n files: string[]\n}\n\nexport function collectRelationshipFields(\n fields: SchemaField[],\n _tabFieldNames: Set<string>\n): SchemaField[] {\n const result: SchemaField[] = []\n const seen = new Set<string>()\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship && !seen.has(f.name)) {\n seen.add(f.name)\n result.push(f)\n }\n if (f.type === 'group' && f.fields) collect(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collect(tab.fields)\n }\n }\n }\n }\n collect(fields)\n return result\n}\n\nexport function generateDefaultValue(f: SchemaField): string {\n if (f.type === 'list') return ` ${f.name}: initialData?.${f.name} ?? []`\n if (f.type === 'boolean') return ` ${f.name}: initialData?.${f.name} ?? false`\n if (f.type === 'number' || f.type === 'decimal' || f.type === 'serial') {\n const def = f.required ? '0' : 'undefined'\n return ` ${f.name}: initialData?.${f.name} ?? ${def}`\n }\n if (f.type === 'relationship') {\n if (f.multiple) return ` ${f.name}: initialData?.${f.name} ?? []`\n return ` ${f.name}: initialData?.${f.name}\n ? (typeof initialData.${f.name} === 'object' ? String(initialData.${f.name}.id) : String(initialData.${f.name}))\n : ''`\n }\n if (f.type === 'date' || f.type === 'timestamp') {\n return ` ${f.name}: initialData?.${f.name} ?? undefined`\n }\n if (f.default !== undefined && f.default !== null) {\n const def = typeof f.default === 'string' ? `'${f.default}'` : f.default\n return ` ${f.name}: initialData?.${f.name} ?? ${def}`\n }\n return ` ${f.name}: initialData?.${f.name} ?? ''`\n}\n\nexport function buildZodFields(flatFields: SchemaField[]): string {\n return flatFields\n .filter((f) => f.type !== 'tabs' && !isLayoutField(f.type))\n .flatMap((f) => {\n const defs: string[] = []\n const zodType = getZodType(f)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(f.name)}: ${zodType}`\n if (!f.required && !alreadyOptional) def += '.optional()'\n defs.push(def)\n if (f.hasIcon) defs.push(` ${quotePropertyName(`${f.name}Icon`)}: z.string().optional()`)\n return defs\n })\n .join(',\\n')\n}\n\nexport function buildDefaultValues(flatFields: SchemaField[]): string {\n return flatFields\n .filter((f) => f.type !== 'tabs' && !isLayoutField(f.type))\n .flatMap((f) => {\n const defs = [generateDefaultValue(f)]\n if (f.hasIcon) defs.push(` ${f.name}Icon: initialData?.${f.name}Icon ?? ''`)\n return defs\n })\n .join(',\\n')\n}\n\nexport function buildUiImports(ctx: {\n hasBoolean: boolean\n hasTextarea: boolean\n hasImage: boolean\n hasVideo: boolean\n hasMedia: boolean\n hasIcon: boolean\n hasIconPostfix: boolean\n hasDate: boolean\n hasMarkdown: boolean\n hasRichtext: boolean\n hasSeparator: boolean\n hasSelect: boolean\n hasTabsField: boolean\n hasRelationship: boolean\n hasSimpleList: boolean\n hasNestedList: boolean\n}): string[] {\n const uiImports: string[] = [\n \"import { Button } from '@cms/components/ui/button'\",\n \"import { Input } from '@cms/components/ui/input'\",\n `import {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage\n} from '@cms/components/ui/form'`\n ]\n\n if (ctx.hasBoolean) uiImports.push(\"import { Checkbox } from '@cms/components/ui/checkbox'\")\n if (ctx.hasTextarea) uiImports.push(\"import { Textarea } from '@cms/components/ui/textarea'\")\n if (ctx.hasImage)\n uiImports.push(\"import { ImageUploadField } from '@cms/components/ui/image-upload-field'\")\n if (ctx.hasVideo)\n uiImports.push(\"import { VideoUploadField } from '@cms/components/ui/video-upload-field'\")\n if (ctx.hasMedia)\n uiImports.push(\"import { MediaUploadField } from '@cms/components/ui/media-upload-field'\")\n if (ctx.hasIcon || ctx.hasIconPostfix)\n uiImports.push(\"import { IconPicker } from '@cms/components/ui/icon-picker'\")\n if (ctx.hasDate) uiImports.push(\"import { DatePicker } from '@cms/components/ui/date-picker'\")\n if (ctx.hasMarkdown)\n uiImports.push(\"import { MarkdownEditor } from '@cms/components/ui/markdown-editor'\")\n if (ctx.hasRichtext)\n uiImports.push(\"import { RichTextEditor } from '@cms/components/ui/rich-text-editor'\")\n if (ctx.hasSeparator) uiImports.push(\"import { Separator } from '@cms/components/ui/separator'\")\n if (ctx.hasSelect) {\n uiImports.push(`import {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue\n} from '@cms/components/ui/select'`)\n }\n if (ctx.hasTabsField) {\n uiImports.push(`import {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent\n} from '@cms/components/ui/tabs'`)\n }\n if (ctx.hasRelationship) {\n uiImports.push(`import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList\n} from '@cms/components/ui/command'`)\n uiImports.push(`import {\n Popover,\n PopoverContent,\n PopoverTrigger\n} from '@cms/components/ui/popover'`)\n }\n\n if (ctx.hasSimpleList)\n uiImports.push(\"import { DynamicListField } from '@cms/components/ui/dynamic-list-field'\")\n if (ctx.hasNestedList) {\n uiImports.push(`import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger\n} from '@cms/components/ui/accordion'`)\n if (!ctx.hasSeparator)\n uiImports.push(\"import { Separator } from '@cms/components/ui/separator'\")\n uiImports.push(\"import { Label } from '@cms/components/ui/label'\")\n }\n\n return uiImports\n}\n","/**\n * Single (singleton) form generator — Card-per-section with independent saves.\n * Top-level `section` fields each become a Card with their own useForm + useMutation.\n * Schemas without sections fall back to a single Card with all fields.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields, hasFieldType, hasIconUsage } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize } from '../../utils/string.js'\nimport { generateFieldJSX } from './field-jsx.js'\nimport {\n type FormGeneratorResult,\n collectRelationshipFields,\n buildZodFields,\n buildDefaultValues,\n buildUiImports\n} from './form-shared.js'\n\n// ============================================================================\n// Card group parsing\n// ============================================================================\n\ninterface CardGroup {\n title: string\n description: string\n varPrefix: string\n componentName: string\n fields: SchemaField[]\n flatFields: SchemaField[]\n}\n\n/**\n * Parse schema fields into card groups.\n * - Top-level `section` fields each become a card.\n * - Fields without sections → one card (backward compat).\n */\nfunction parseCardGroups(allFormFields: SchemaField[], schemaLabel: string): CardGroup[] {\n const sections = allFormFields.filter((f) => f.type === 'section' && f.fields)\n const nonSections = allFormFields.filter((f) => f.type !== 'section' && !isLayoutField(f.type))\n\n // If no sections, all fields go in one card\n if (sections.length === 0) {\n const title = nonSections[0]?.label || nonSections[0]?.name || schemaLabel\n return [\n {\n title,\n description: '',\n varPrefix: toCamelCase(nonSections[0]?.name || 'form'),\n componentName: `${toPascalCase(nonSections[0]?.name || 'form')}Card`,\n fields: nonSections,\n flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))\n }\n ]\n }\n\n // Each section becomes a card\n const groups: CardGroup[] = []\n for (const section of sections) {\n const innerFields = section.fields || []\n groups.push({\n title: section.label || section.name,\n description: section.description || section.hint || '',\n varPrefix: toCamelCase(section.name),\n componentName: `${toPascalCase(section.name)}Card`,\n fields: innerFields,\n flatFields: flattenFields(innerFields).filter((f) => !isLayoutField(f.type))\n })\n }\n\n // If there are also loose fields outside sections, put them in a default card\n if (nonSections.length > 0) {\n const title = nonSections[0]?.label || nonSections[0]?.name || 'General'\n groups.unshift({\n title,\n description: '',\n varPrefix: toCamelCase(nonSections[0]?.name || 'general'),\n componentName: `${toPascalCase(nonSections[0]?.name || 'General')}Card`,\n fields: nonSections,\n flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))\n })\n }\n\n return groups\n}\n\n// ============================================================================\n// Per-group analysis\n// ============================================================================\n\ninterface GroupAnalysis {\n relFields: SchemaField[]\n listFieldsWithNested: SchemaField[]\n hasTabsField: boolean\n firstTabName: string\n tabFieldNames: Set<string>\n}\n\nfunction analyzeGroup(fields: SchemaField[]): GroupAnalysis {\n const tabFieldNames = new Set<string>()\n for (const f of fields) {\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) for (const tf of tab.fields) tabFieldNames.add(tf.name)\n }\n }\n }\n\n const relFields = collectRelationshipFields(fields, tabFieldNames)\n\n const listFieldsWithNested: SchemaField[] = []\n function collectLists(flds: SchemaField[]): void {\n for (const f of flds) {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n listFieldsWithNested.push(f)\n }\n if (f.type === 'group' && f.fields) collectLists(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collectLists(tab.fields)\n }\n }\n }\n }\n collectLists(fields)\n\n const hasTabsField = fields.some((f) => f.type === 'tabs')\n const tabsField = fields.find((f) => f.type === 'tabs')\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n return { relFields, listFieldsWithNested, hasTabsField, firstTabName, tabFieldNames }\n}\n\n// ============================================================================\n// Per-group JSX generation\n// ============================================================================\n\nfunction buildGroupFieldsJSX(\n group: CardGroup,\n analysis: GroupAnalysis,\n skipLabel: boolean\n): string {\n const indent = ' '\n return group.fields\n .map((f) => {\n if (f.type === 'tabs' && f.tabs) {\n const tabsList = f.tabs\n .map((t) => ` <TabsTrigger value=\"${t.name}\">${t.label}</TabsTrigger>`)\n .join('\\n')\n const tabsContent = f.tabs\n .map((t) => {\n const tabFields = (t.fields || [])\n .map((tf) => generateFieldJSX(tf, ' '))\n .join('\\n')\n return ` <TabsContent value=\"${t.name}\" className=\"space-y-6\">\n${tabFields}\n </TabsContent>`\n })\n .join('\\n')\n return `${indent}<Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n${indent}</Tabs>`\n }\n if (analysis.tabFieldNames.has(f.name)) return ''\n return generateFieldJSX(f, indent, { skipLabel })\n })\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction buildGroupRelState(analysis: GroupAnalysis): string {\n return analysis.relFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return ` const [${f.name}Open, set${toPascalCase(f.name)}Open] = React.useState(false)\n const { data: ${f.relationship}Data } = use${relPlural}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n}\n\nfunction buildGroupFieldArrayHooks(analysis: GroupAnalysis): string {\n return analysis.listFieldsWithNested\n .map((field) => {\n const pascalFieldName = toPascalCase(field.name)\n return ` const [${field.name}Expanded, set${pascalFieldName}Expanded] = React.useState<string | undefined>(undefined)\n const ${field.name}FieldArray = useFieldArray({\n control: form.control,\n name: '${field.name}'\n })`\n })\n .join('\\n')\n}\n\n// ============================================================================\n// Card component generation\n// ============================================================================\n\nfunction generateCardComponent(\n group: CardGroup,\n schema: Schema,\n analysis: GroupAnalysis\n): string {\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n const zodFields = buildZodFields(group.flatFields)\n const defaultValues = buildDefaultValues(group.flatFields)\n const isSingleField = group.fields.length === 1 && group.title === (group.fields[0].label || group.fields[0].name)\n const fieldsJSX = buildGroupFieldsJSX(group, analysis, isSingleField)\n const relState = buildGroupRelState(analysis)\n const fieldArrayHooks = buildGroupFieldArrayHooks(analysis)\n\n const descriptionLine = group.description\n ? `\\n <CardDescription>${group.description}</CardDescription>`\n : ''\n\n return `const ${group.varPrefix}Schema = z.object({\n${zodFields}\n})\n\nfunction ${group.componentName}({ initialData }: { initialData?: ${Singular}Data | null }) {\n const queryClient = useQueryClient()${analysis.hasTabsField ? `\\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${analysis.firstTabName}' })` : ''}${relState ? `\\n${relState}` : ''}\n\n const mutation = useMutation({\n mutationFn: (data: Upsert${Singular}Input) => upsert${Singular}(data),\n onSuccess: () => {\n toast.success('${group.title} saved')\n queryClient.invalidateQueries({ queryKey: ['${schema.name}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to save')\n }\n })\n\n const isPending = mutation.isPending\n\n const form = useForm<z.infer<typeof ${group.varPrefix}Schema>>({\n resolver: zodResolver(${group.varPrefix}Schema),\n defaultValues: {\n${defaultValues}\n }\n })\n${fieldArrayHooks ? `\\n${fieldArrayHooks}\\n` : ''}\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit((values) => {\n const cleaned = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [key, value === undefined ? '' : value])\n )\n mutation.mutate(cleaned as Upsert${Singular}Input)\n })}>\n <Card className=\"material-sm!\">\n <CardHeader>\n <CardTitle>${group.title}</CardTitle>${descriptionLine}\n </CardHeader>\n <CardContent className=\"space-y-6\">\n${fieldsJSX}\n </CardContent>\n <CardFooter>\n <Button type=\"submit\" disabled={isPending} size=\"sm\">\n {isPending ? 'Saving...' : 'Save'}\n </Button>\n </CardFooter>\n </Card>\n </form>\n </Form>\n )\n}`\n}\n\n// ============================================================================\n// Main generator\n// ============================================================================\n\nexport function generateSingleForm(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): FormGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const formFilePath = path.join(entityDir, `${schema.name}-form.tsx`)\n\n if (fs.existsSync(formFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n // Filter out auto-generated fields\n const allFormFields = schema.fields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n\n // Parse into card groups\n const cardGroups = parseCardGroups(allFormFields, schema.label)\n\n // --- Global field analysis for imports ---\n const hasBoolean = hasFieldType(schema.fields, 'boolean')\n const hasImage = hasFieldType(schema.fields, 'image')\n const hasVideo = hasFieldType(schema.fields, 'video')\n const hasMedia = hasFieldType(schema.fields, 'media')\n const hasIcon = hasFieldType(schema.fields, 'icon')\n const hasIconPostfix = hasIconUsage(schema.fields)\n const hasDate = hasFieldType(schema.fields, 'date')\n const hasSelect = hasFieldType(schema.fields, 'select')\n const hasMarkdown = hasFieldType(schema.fields, 'markdown')\n const hasRichtext = hasFieldType(schema.fields, 'richtext')\n const hasTextarea = hasFieldType(schema.fields, 'text')\n const hasSeparator = hasFieldType(schema.fields, 'separator')\n const hasRelationship = hasFieldType(schema.fields, 'relationship')\n const hasTabsField = schema.fields.some((f) => f.type === 'tabs')\n const flatFields = flattenFields(allFormFields)\n const hasList = hasFieldType(schema.fields, 'list')\n const hasNestedList = cardGroups.some((g) => analyzeGroup(g.fields).listFieldsWithNested.length > 0)\n const hasSimpleList =\n hasList && flatFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n\n // Global relationship hooks for imports\n const allRelFields: SchemaField[] = []\n for (const g of cardGroups) {\n const a = analyzeGroup(g.fields)\n for (const rf of a.relFields) {\n if (!allRelFields.some((e) => e.relationship === rf.relationship)) {\n allRelFields.push(rf)\n }\n }\n }\n\n const needsReact = allRelFields.length > 0 || hasNestedList\n\n // --- Build imports ---\n const uiImports = buildUiImports({\n hasBoolean,\n hasTextarea,\n hasImage,\n hasVideo,\n hasMedia,\n hasIcon,\n hasIconPostfix,\n hasDate,\n hasMarkdown,\n hasRichtext,\n hasSeparator,\n hasSelect,\n hasTabsField,\n hasRelationship,\n hasSimpleList,\n hasNestedList\n })\n\n // Add Card imports\n uiImports.push(`import {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle\n} from '@cms/components/ui/card'`)\n\n // Lucide icons\n const lucideIcons: string[] = []\n if (hasRelationship) lucideIcons.push('Check', 'ChevronsUpDown')\n if (hasNestedList) {\n if (!lucideIcons.includes('Plus')) lucideIcons.push('Plus')\n if (!lucideIcons.includes('X')) lucideIcons.push('X')\n }\n\n // Relationship hook imports\n const relHookImports = allRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relPlural} } from '@cms/hooks/use-${f.relationship}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // --- Generate per-group card components ---\n const cardComponents = cardGroups.map((group) => {\n const analysis = analyzeGroup(group.fields)\n return generateCardComponent(group, schema, analysis)\n })\n\n // --- Generate parent component ---\n const cardRenders = cardGroups\n .map((g) => ` <${g.componentName} initialData={initialData} />`)\n .join('\\n')\n\n // --- Assemble file ---\n const content = `'use client'\n${needsReact ? \"\\nimport * as React from 'react'\" : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideIcons.length > 0 ? `\\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\nimport {${hasNestedList ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod/v3'${hasTabsField ? \"\\nimport { useQueryState } from 'nuqs'\" : ''}${hasRelationship ? \"\\nimport { cn } from '@cms/utils/cn'\" : ''}\n${relHookImports ? `${relHookImports}\\n` : ''}${uiImports.join('\\n')}\nimport type {\n ${Singular}Data,\n Upsert${Singular}Input\n} from '@cms/actions/${schema.name}'\nimport { upsert${Singular} } from '@cms/actions/${schema.name}'\n\n${cardComponents.join('\\n\\n')}\n\ninterface ${Singular}FormProps {\n initialData?: ${Singular}Data | null\n}\n\nexport function ${Singular}Form({ initialData }: ${Singular}FormProps) {\n return (\n <div className=\"space-y-6\">\n${cardRenders}\n </div>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, `${schema.name}-form.tsx`)]\n }\n}\n","/**\n * Generator 3: React Query hook — cms/hooks/use-<n>.ts\n * Generates client-side data fetching hooks wrapping server actions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, pluralize } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface HookGeneratorResult {\n files: string[]\n hookName: string\n}\n\n/**\n * Generate React Query hook for an entity — writes to cms/hooks/use-<n>.ts\n */\nexport function generateHook(\n schema: Schema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions = {}\n): HookGeneratorResult {\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(cwd, hooksDir, hookFileName)\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n\n // Check if schema has a slug field\n const dbFields = flattenFields(schema.fields)\n const hasSlugField = dbFields.some((f) => f.name === 'slug')\n const hasHtmlOutput = dbFields.some(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n\n // Check for existing file\n if (fs.existsSync(hookFilePath) && !options.force) {\n return { files: [], hookName: `use${Plural}` }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // --- Build imports from actions ---\n const actionImports: string[] = [`get${Plural}`, `get${Singular}ById`]\n if (hasSlugField) actionImports.push(`get${Singular}BySlug`)\n if (hasFilters) {\n for (const filter of schema.filters!) {\n actionImports.push(`getDistinct${Plural}${toPascalCase(filter.field)}`)\n }\n }\n const typeImports = [\n `type ${Singular}Data`,\n ...(hasHtmlOutput && hasSlugField ? [`type ${Singular}DisplayData`] : []),\n `type ${Plural}Response`,\n `type Get${Plural}Filters`\n ]\n\n // --- Build filter parameters ---\n const filterParams = hasFilters\n ? schema.filters!.map((f) => `${f.field}?: string`).join(', ')\n : ''\n const allParams = filterParams ? `search?: string, ${filterParams}` : 'search?: string'\n\n // --- Build query key with all filter params ---\n const queryKeyParts = hasFilters\n ? [\"search ?? ''\", ...schema.filters!.map((f) => `${f.field} ?? ''`)].join(', ')\n : \"search ?? ''\"\n\n // --- Build filters object in queryFn ---\n const filtersBody = hasFilters\n ? `const filters: Get${Plural}Filters = {}\n if (search) filters.search = search\n${schema.filters!.map((f) => ` if (${f.field}) filters.${f.field} = ${f.field}`).join('\\n')}\n return get${Plural}(Object.keys(filters).length > 0 ? filters : undefined)`\n : `const filters: Get${Plural}Filters | undefined = search ? { search } : undefined\n return get${Plural}(filters)`\n\n // --- Singular hook ---\n const singularHook = `\nexport function use${Singular}(id: number | null | undefined): UseQueryResult<${Singular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singular}', id],\n queryFn: () => (id ? get${Singular}ById(id) : Promise.resolve(null)),\n enabled: !!id,\n staleTime: 0\n })\n}`\n\n // --- Slug hook ---\n const slugReturnType = hasHtmlOutput ? `${Singular}DisplayData` : `${Singular}Data`\n const slugHook = hasSlugField\n ? `\n\nexport function use${Singular}BySlug(slug: string | null | undefined): UseQueryResult<${slugReturnType} | null, Error> {\n return useQuery({\n queryKey: ['${singular}', 'slug', slug],\n queryFn: () => (slug ? get${Singular}BySlug(slug) : Promise.resolve(null)),\n enabled: !!slug,\n staleTime: 0\n })\n}`\n : ''\n\n // --- Distinct filter hooks ---\n const distinctHooks = hasFilters\n ? schema\n .filters!.map(\n (filter) => `\n\nexport function use${Plural}Distinct${toPascalCase(filter.field)}(): UseQueryResult<string[], Error> {\n return useQuery({\n queryKey: ['${plural}', 'distinct', '${filter.field}'],\n queryFn: () => getDistinct${Plural}${toPascalCase(filter.field)}()\n })\n}`\n )\n .join('')\n : ''\n\n // --- Assemble file ---\n const content = `import {\n ${[...actionImports, ...typeImports].join(',\\n ')}\n} from '@cms/actions/${schema.name}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${Plural}(\n ${allParams ? `${allParams},` : ''}\n options?: { enabled?: boolean }\n): UseQueryResult<${Plural}Response, Error> {\n return useQuery({\n queryKey: ['${plural}', ${queryKeyParts}],\n queryFn: () => {\n ${filtersBody}\n },\n enabled: options?.enabled ?? true,\n refetchOnMount: 'always'\n })\n}\n${singularHook}${slugHook}${distinctHooks}\n`\n\n // Write file\n const dir = path.dirname(hookFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n return {\n files: [path.join(hooksDir, hookFileName)],\n hookName: `use${Plural}`\n }\n}\n\n/**\n * Generate React Query hook for a single (singleton) schema.\n * Only useXxx() query — no list, slug, or filter hooks.\n */\nexport function generateSingleHook(\n schema: Schema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions = {}\n): HookGeneratorResult {\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(cwd, hooksDir, hookFileName)\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n if (fs.existsSync(hookFilePath) && !options.force) {\n return { files: [], hookName: `use${Singular}` }\n }\n\n const content = `import {\n get${Singular},\n type ${Singular}Data\n} from '@cms/actions/${schema.name}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${Singular}(): UseQueryResult<${Singular}Data | null, Error> {\n return useQuery({\n queryKey: ['${schema.name}'],\n queryFn: () => get${Singular}(),\n staleTime: 0\n })\n}\n`\n\n const dir = path.dirname(hookFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n return {\n files: [path.join(hooksDir, hookFileName)],\n hookName: `use${Singular}`\n }\n}\n","/**\n * Generator 11: Navigation — append to cms/data/navigation.ts\n * Parses existing navigation file and inserts new entity entry.\n * Uses flat `group` property for sidebar grouping (no nested children).\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface NavItem {\n label: string\n href: string\n icon?: string\n group?: string\n}\n\n// ============================================================================\n// Parser\n// ============================================================================\n\n/**\n * Parse existing navigation.ts and extract nav items + icon imports\n */\nfunction parseNavigationFile(content: string): { items: NavItem[]; iconImports: string[] } {\n const iconImportMatch = content.match(/import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]lucide-react['\"]/)\n const iconImports: string[] = iconImportMatch\n ? iconImportMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s && s !== 'LucideIcon')\n : []\n\n const arrayBlock = extractTopLevelArray(content)\n if (!arrayBlock) return { items: [], iconImports }\n\n const items = parseItemsBlock(arrayBlock)\n return { items, iconImports }\n}\n\n/**\n * Find the cmsNavigation array and extract its content using bracket counting\n */\nfunction extractTopLevelArray(content: string): string | null {\n const marker = content.indexOf('cmsNavigation')\n if (marker === -1) return null\n\n const eqSign = content.indexOf('=', marker)\n if (eqSign === -1) return null\n const openBracket = content.indexOf('[', eqSign)\n if (openBracket === -1) return null\n\n let depth = 0\n for (let i = openBracket; i < content.length; i++) {\n if (content[i] === '[') depth++\n if (content[i] === ']') depth--\n if (depth === 0) {\n return content.slice(openBracket + 1, i)\n }\n }\n return null\n}\n\nfunction parseItemsBlock(block: string): NavItem[] {\n const items: NavItem[] = []\n let depth = 0\n let current = ''\n let inObj = false\n\n for (const char of block) {\n if (char === '{') {\n if (depth === 0) inObj = true\n depth++\n current += char\n } else if (char === '}') {\n depth--\n current += char\n if (depth === 0 && inObj) {\n const item = parseSingleItem(current)\n if (item) items.push(item)\n current = ''\n inObj = false\n }\n } else if (inObj) {\n current += char\n }\n }\n\n return items\n}\n\nfunction parseSingleItem(str: string): NavItem | null {\n const labelMatch = str.match(/label:\\s*['\"]([^'\"]+)['\"]/)\n const hrefMatch = str.match(/href:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = str.match(/icon:\\s*(\\w+)/)\n const groupMatch = str.match(/group:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!labelMatch || !hrefMatch) return null\n\n const item: NavItem = {\n label: labelMatch[1],\n href: hrefMatch[1]\n }\n if (iconMatch) item.icon = iconMatch[1]\n if (groupMatch) item.group = groupMatch[1]\n\n return item\n}\n\n// ============================================================================\n// Code Generator\n// ============================================================================\n\nfunction generateNavigationCode(items: NavItem[], iconImports: string[]): string {\n const lines: string[] = []\n\n lines.push(\"import type { LucideIcon } from 'lucide-react'\")\n lines.push(`import { ${iconImports.join(', ')} } from 'lucide-react'`)\n lines.push('')\n lines.push('export interface CmsNavigationItem {')\n lines.push(' label: string')\n lines.push(' href: string')\n lines.push(' icon?: LucideIcon')\n lines.push(' group?: string')\n lines.push('}')\n lines.push('')\n lines.push('export const cmsNavigation: CmsNavigationItem[] = [')\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n appendItem(lines, item, isLast)\n }\n\n lines.push(']')\n lines.push('')\n\n return lines.join('\\n')\n}\n\nfunction appendItem(lines: string[], item: NavItem, isLast: boolean): void {\n lines.push(' {')\n lines.push(` label: '${item.label}',`)\n\n const hasMore = item.icon != null || item.group != null\n lines.push(` href: '${item.href}'${hasMore ? ',' : ''}`)\n\n if (item.icon && item.group) {\n lines.push(` icon: ${item.icon},`)\n lines.push(` group: '${item.group}'`)\n } else if (item.icon) {\n lines.push(` icon: ${item.icon}`)\n } else if (item.group) {\n lines.push(` group: '${item.group}'`)\n }\n\n lines.push(` }${isLast ? '' : ','}`)\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface NavigationGeneratorResult {\n files: string[]\n}\n\n/**\n * Update cms/data/navigation.ts to include new entity nav item\n */\nexport function updateNavigation(\n schema: Schema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): NavigationGeneratorResult {\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n\n // Settings lives in the sidebar footer, not in navigation\n if (schema.name === 'settings') {\n return { files: [] }\n }\n\n // Parse existing navigation\n let items: NavItem[] = []\n let iconImports: string[] = []\n\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const parsed = parseNavigationFile(content)\n items = parsed.items\n iconImports = parsed.iconImports\n }\n\n const entityHref = `/cms/${schema.name}`\n\n const newItem: NavItem = {\n label: schema.label,\n href: entityHref,\n icon: schema.icon\n }\n\n // If schema has a navGroup, set the group property\n if (schema.navGroup) {\n newItem.group = schema.navGroup.label\n }\n\n // Check if item already exists\n const existingIndex = items.findIndex((item) => item.href === entityHref)\n\n if (existingIndex >= 0) {\n if (options.force) {\n items[existingIndex] = newItem\n } else {\n return { files: [] }\n }\n } else {\n items.push(newItem)\n }\n\n // Reorganize: Dashboard first, then ungrouped alphabetical, then grouped alphabetical\n const dashboard = items.find((item) => item.href === '/cms')\n const others = items.filter((item) => item.href !== '/cms')\n others.sort((a, b) => {\n // Ungrouped items first, then by group name, then by label\n if (!a.group && b.group) return -1\n if (a.group && !b.group) return 1\n if (a.group && b.group && a.group !== b.group) return a.group.localeCompare(b.group)\n return a.label.localeCompare(b.label)\n })\n\n items = [...(dashboard ? [dashboard] : []), ...others]\n\n // Add icon import if needed\n if (schema.icon && !iconImports.includes(schema.icon)) {\n iconImports.push(schema.icon)\n }\n iconImports.sort()\n\n // Write updated file\n const dir = path.dirname(navFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n\n const code = generateNavigationCode(items, iconImports)\n fs.writeFileSync(navFilePath, code, 'utf-8')\n\n return {\n files: [path.join(cmsDir, 'data', 'navigation.ts')]\n }\n}\n","/**\n * Generator 7: Page (server) — (authenticated)/<n>/page.tsx\n * Generates the server page component that renders columns + page content\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, pluralize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface PageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate server page component for entity list view\n */\nexport function generatePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): PageGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const pageFilePath = path.join(entityDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const plural = pluralize(schema.name)\n const Plural = toPascalCase(plural)\n const kebabPlural = toKebabCase(plural)\n\n const content = `import * as React from 'react'\nimport { columns } from './columns'\nimport { ${Plural}PageContent } from './${kebabPlural}-page-content'\n\nexport default function ${Plural}Page() {\n return (\n <React.Suspense\n fallback={\n <div className=\"flex items-center justify-center h-48\">\n <div className=\"text-muted-foreground\">Loading ${schema.label}...</div>\n </div>\n }\n >\n <div className=\"flex flex-col\">\n <${Plural}PageContent columns={columns} />\n </div>\n </React.Suspense>\n )\n}\n`\n\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'page.tsx')]\n }\n}\n","/**\n * Generator 6: Page content — (authenticated)/<n>/<n>-page-content.tsx\n * Generates client component with search, filters, bulk delete, and table\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, pluralize, singularizeLabel, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface PageContentGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate page content component for entity list view\n */\nexport function generatePageContent(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): PageContentGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const fileName = `${toKebabCase(plural)}-page-content.tsx`\n const filePath = path.join(entityDir, fileName)\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [] }\n }\n\n const hasCreate = schema.actions?.create ?? false\n const hasDelete = schema.actions?.delete ?? false\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // --- Lucide icons ---\n const lucideIcons: string[] = ['ChevronLeft', 'Search', 'CornerDownLeft']\n if (hasCreate) lucideIcons.push('Plus')\n if (hasDelete) lucideIcons.push('Trash2')\n if (hasFilters) lucideIcons.push('Check', 'ChevronsUpDown')\n\n // --- Build imports ---\n let imports = `'use client'\n\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'\n${hasCreate ? \"import Link from 'next/link'\\n\" : ''}import { useRouter } from 'next/navigation'\nimport { parseAsString${hasDelete ? ', parseAsArrayOf, parseAsInteger' : ''}, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\n${hasDelete ? \"import { toast } from 'sonner'\\n\" : ''}import { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\n`\n\n if (hasDelete) {\n imports += `import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger\n} from '@cms/components/ui/alert-dialog'\n`\n }\n\n if (hasFilters) {\n imports += `import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList\n} from '@cms/components/ui/command'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger\n} from '@cms/components/ui/popover'\nimport { cn } from '@cms/utils/cn'\n`\n // Filter hooks\n const filterHooks = schema\n .filters!.map((f) => `use${Plural}Distinct${toPascalCase(f.field)}`)\n .join(', ')\n imports += `import { ${filterHooks} } from '@cms/hooks/use-${schema.name}'\\n`\n }\n\n imports += `import type { ${Singular}Data } from '@cms/actions/${schema.name}'\n${hasDelete ? `import { deleteBulk${Plural} } from '@cms/actions/${schema.name}'\\n` : ''}import { ${Plural}Table } from './${toKebabCase(plural)}-table'\n`\n\n // --- SearchButton component ---\n const searchButton = `function SearchButton() {\n const { pending } = useFormStatus()\n return (\n <Button type=\"submit\" variant=\"outline\" size=\"default\" disabled={pending}>\n {pending ? 'Searching...' : 'Search'}\n </Button>\n )\n}\n\n`\n\n // --- Filter state ---\n const filterLogic = hasFilters\n ? schema\n .filters!.map(\n (f) =>\n ` const [${f.field}, set${toPascalCase(f.field)}] = useQueryState('${f.field}', parseAsString.withDefault(''))\n const { data: ${f.field}Options } = use${Plural}Distinct${toPascalCase(f.field)}()\n const [${f.field}ComboboxOpen, set${toPascalCase(f.field)}ComboboxOpen] = React.useState(false)`\n )\n .join('\\n')\n : ''\n\n // --- Search logic ---\n const searchLogic = ` const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n\n const searchAction = React.useCallback(async (formData: FormData) => {\n const value = formData.get('search') as string\n React.startTransition(() => {\n setSearch(value || null)\n })\n }, [setSearch])\n${filterLogic ? `\\n${filterLogic}` : ''}`\n\n // --- Delete logic ---\n const deleteLogic = hasDelete\n ? `\n const [selectedIds, setSelectedIds] = useQueryState(\n 'selected',\n parseAsArrayOf(parseAsInteger).withDefault([])\n )\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false)\n const [isPending, startTransition] = React.useTransition()\n\n const handleBulkDelete = () => {\n startTransition(async () => {\n try {\n const result = await deleteBulk${Plural}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} ${singular}\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${plural}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n`\n : ''\n\n // --- Filter dropdowns ---\n const _filterDropdowns = hasFilters\n ? schema\n .filters!.map(\n (\n f\n ) => ` <Popover open={${f.field}ComboboxOpen} onOpenChange={set${toPascalCase(f.field)}ComboboxOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={${f.field}ComboboxOpen}\n className=\"w-[200px] justify-between\"\n >\n {${f.field} || '${f.label}'}\n <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n key=\"all\"\n value=\"\"\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(f.field)}('')\n })\n set${toPascalCase(f.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 size-4',\n ${f.field} === '' ? 'opacity-100' : 'opacity-0'\n )}\n />\n All ${f.label}\n </CommandItem>\n {${f.field}Options?.map((option) => (\n <CommandItem\n key={option}\n value={option}\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(f.field)}(option)\n })\n set${toPascalCase(f.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 size-4',\n ${f.field} === option ? 'opacity-100' : 'opacity-0'\n )}\n />\n {option}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>`\n )\n .join('\\n')\n : ''\n\n // --- Search input ---\n const searchInput = `<form action={searchAction} className=\"flex items-center gap-2 relative\">\n <Search className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n key={search}\n name=\"search\"\n placeholder=\"Search ${schema.label.toLowerCase()}...\"\n defaultValue={search}\n className=\"w-64 pl-9 bg-white rounded-lg\"\n />\n <CornerDownLeft className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2\" />\n </form>`\n\n // --- Delete button ---\n const deleteButton = hasDelete\n ? ` {selectedIds.length > 0 && (\n <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"default\">\n <Trash2 className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? '${singular}' : '${plural}'}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? '${singular}' : '${plural}'}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault()\n handleBulkDelete()\n }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}`\n : ''\n\n // --- Create button ---\n const createButton = hasCreate\n ? ` <Button asChild>\n <Link href=\"/cms/${schema.name}/new\">\n <Plus className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Create ${singularizeLabel(schema.label)}\n </Link>\n </Button>`\n : ''\n\n // --- Table props ---\n const filterPropsStr = hasFilters\n ? schema.filters!.map((f) => `${f.field}={${f.field}}`).join(' ')\n : ''\n const allTableProps = filterPropsStr ? `search={search} ${filterPropsStr}` : 'search={search}'\n const tableProps = hasDelete\n ? `columns={columns} selectedIds={selectedIds} setSelectedIds={setSelectedIds} ${allTableProps}`\n : `columns={columns} selectedIds={[]} setSelectedIds={() => {}} ${allTableProps}`\n\n // --- Assemble file ---\n const content = `${imports}\n${searchButton}interface ${Plural}PageContentProps<TValue> {\n columns: ColumnDef<${Singular}Data, TValue>[]\n}\n\nexport function ${Plural}PageContent<TValue>({\n columns\n}: ${Plural}PageContentProps<TValue>) {\n const router = useRouter()\n const queryClient = useQueryClient()\n${searchLogic}${deleteLogic}\n return (\n <>\n <PageHeader title=\"${schema.label}\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} search={${searchInput}} actions={<div className=\"flex items-center gap-2\">${deleteButton} ${createButton}</div>} />\n <main className=\"space-y-6 p-6\">\n <${Plural}Table ${tableProps} />\n </main>\n </>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, fileName)]\n }\n}\n","/**\n * Generator: Single page — (authenticated)/<n>/page.tsx\n * Server component that fetches the singleton record and renders the form.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface SinglePageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate server page for a single (singleton) schema.\n * Calls getXxx() and renders XxxForm with initialData (null on first visit).\n */\nexport function generateSinglePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): SinglePageGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const pageFilePath = path.join(entityDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const PageName = toPascalCase(schema.name)\n\n const content = `import { get${Singular} } from '@cms/actions/${schema.name}'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { ${Singular}Form } from './${schema.name}-form'\nimport { connection } from 'next/server'\n\nexport default async function ${PageName}Page() {\n await connection()\n const data = await get${Singular}()\n\n return (\n <>\n <PageHeader title=\"${schema.label}\" />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form initialData={data} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'page.tsx')]\n }\n}\n","/**\n * Generator 5: Table component — (authenticated)/<n>/<n>-table.tsx\n * Generates data table with pagination, sorting, reorder, and row selection\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface TableGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate table component for entity list view\n */\nexport function generateTable(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): TableGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const camelPlural = toCamelCase(plural)\n const camelSingular = toCamelCase(singular)\n const tableFileName = `${toKebabCase(plural)}-table.tsx`\n const tableFilePath = path.join(entityDir, tableFileName)\n\n if (fs.existsSync(tableFilePath) && !options.force) {\n return { files: [] }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n const filterProps = hasFilters\n ? schema.filters!.map((f) => `${f.field}?: string`).join('\\n ')\n : ''\n const allFilterProps = filterProps ? `\\n ${filterProps}` : ''\n const filterParams = hasFilters ? schema.filters!.map((f) => f.field).join(', ') : ''\n const allParams = filterParams ? `search, ${filterParams}` : 'search'\n\n const content = `'use client'\n\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type SortingState,\n useReactTable,\n type VisibilityState\n} from '@tanstack/react-table'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { Button } from '@cms/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue\n} from '@cms/components/ui/select'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '@cms/components/ui/table'\nimport { use${Plural} } from '@cms/hooks/use-${schema.name}'\nimport { bulkUpdate${Plural}SortOrder } from '@cms/actions/${schema.name}'\nimport type { ${Singular}Data } from '@cms/actions/${schema.name}'\nimport '@cms/types/table-meta'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ArrowUpDown, Save } from 'lucide-react'\nimport { toast } from 'sonner'\n\nconst PAGE_SIZE_OPTIONS = [\n { value: '10', label: '10' },\n { value: '20', label: '20' },\n { value: '50', label: '50' },\n { value: '100', label: '100' },\n { value: 'all', label: 'All' }\n]\n\ninterface ${Plural}TableProps<TValue> {\n columns: ColumnDef<${Singular}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string${allFilterProps}\n}\n\nexport function ${Plural}Table<TValue>({ columns, selectedIds, setSelectedIds, ${allParams} }: ${Plural}TableProps<TValue>) {\n const { data, error, isPending } = use${Plural}(${allParams})\n const queryClient = useQueryClient()\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})\n const [pageIndex, setPageIndex] = useQueryState('page', parseAsInteger.withDefault(0))\n const [pageSize, setPageSize] = useQueryState('size', parseAsInteger.withDefault(20))\n\n // Reorder mode state\n const [reorderMode, setReorderMode] = React.useState(false)\n const [localData, setLocalData] = React.useState<${Singular}Data[]>([])\n const [hasChanges, setHasChanges] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n\n // Sync local data when server data changes\n React.useEffect(() => {\n if (data?.${camelPlural}) {\n setLocalData([...data.${camelPlural}])\n setHasChanges(false)\n }\n }, [data?.${camelPlural}])\n\n // Handle local row move (client-side only)\n const handleMoveRow = React.useCallback((id: number, direction: 'up' | 'down') => {\n setLocalData((prev) => {\n const index = prev.findIndex((item) => item.id === id)\n if (index === -1) return prev\n\n const newIndex = direction === 'up' ? index - 1 : index + 1\n if (newIndex < 0 || newIndex >= prev.length) return prev\n\n const newData = [...prev]\n const [removed] = newData.splice(index, 1)\n newData.splice(newIndex, 0, removed)\n\n return newData\n })\n setHasChanges(true)\n }, [])\n\n // Save all sort order changes to the database\n const handleSave = React.useCallback(async () => {\n if (!hasChanges) return\n\n setIsSaving(true)\n try {\n const updates = localData.map((item, index) => ({\n id: item.id as number,\n sortOrder: index\n }))\n\n const result = await bulkUpdate${Plural}SortOrder(updates)\n\n if (result.success) {\n toast.success('Sort order saved successfully')\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setHasChanges(false)\n setReorderMode(false)\n } else {\n toast.error(result.error || 'Failed to save sort order')\n }\n } catch (error) {\n toast.error('An error occurred while saving')\n console.error(error)\n } finally {\n setIsSaving(false)\n }\n }, [hasChanges, localData, queryClient])\n\n // Cancel reorder mode and reset changes\n const handleCancelReorder = React.useCallback(() => {\n if (data?.${camelPlural}) {\n setLocalData([...data.${camelPlural}])\n }\n setHasChanges(false)\n setReorderMode(false)\n }, [data?.${camelPlural}])\n\n // Use local data when in reorder mode, otherwise use server data\n const tableData = reorderMode ? localData : (data?.${camelPlural} ?? [])\n\n // Convert selectedIds array to rowSelection object format\n const rowSelection = React.useMemo(() => {\n const selection: Record<string, boolean> = {}\n const ${camelPlural} = data?.${camelPlural} ?? []\n ${camelPlural}.forEach((${camelSingular}, index) => {\n if (selectedIds.includes(${camelSingular}.id as number)) {\n selection[index.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.${camelPlural}])\n\n // Handle row selection changes\n const handleRowSelectionChange = React.useCallback(\n (updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)) => {\n const ${camelPlural} = data?.${camelPlural} ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n\n const newSelectedIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => ${camelPlural}[Number.parseInt(key)]?.id as number)\n .filter(Boolean)\n\n setSelectedIds(newSelectedIds)\n },\n [data?.${camelPlural}, rowSelection, setSelectedIds]\n )\n\n // Determine effective page size (handle 'all' case)\n const effectivePageSize = pageSize === -1 ? Number.MAX_SAFE_INTEGER : pageSize\n\n const handlePageSizeChange = React.useCallback((value: string) => {\n React.startTransition(() => {\n if (value === 'all') {\n setPageSize(-1)\n } else {\n setPageSize(Number(value))\n }\n setPageIndex(0)\n })\n }, [setPageSize, setPageIndex])\n\n const handlePaginationChange = React.useCallback(\n (updater: { pageIndex: number; pageSize: number } | ((old: { pageIndex: number; pageSize: number }) => { pageIndex: number; pageSize: number })) => {\n const currentPagination = { pageIndex, pageSize: effectivePageSize }\n const newPagination = typeof updater === 'function' ? updater(currentPagination) : updater\n React.startTransition(() => {\n setPageIndex(newPagination.pageIndex)\n })\n },\n [pageIndex, effectivePageSize, setPageIndex]\n )\n\n const table = useReactTable({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: handleRowSelectionChange,\n onPaginationChange: handlePaginationChange,\n meta: {\n reorderMode,\n onMoveRow: handleMoveRow\n },\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n pagination: {\n pageIndex,\n pageSize: effectivePageSize\n }\n }\n })\n\n return (\n <div className=\"space-y-6\">\n {/* Reorder controls */}\n <div className=\"flex items-center gap-2\">\n <Button\n variant={reorderMode ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setReorderMode(!reorderMode)}\n disabled={isSaving}\n >\n <ArrowUpDown className=\"size-4 mr-1\" />\n Sort Order\n </Button>\n {reorderMode && (\n <>\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={handleSave}\n disabled={!hasChanges || isSaving}\n >\n <Save className=\"size-4 mr-1\" />\n {isSaving ? 'Saving...' : 'Save'}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancelReorder}\n disabled={isSaving}\n >\n Cancel\n </Button>\n {hasChanges && (\n <span className=\"text-sm text-muted-foreground\">\n Unsaved changes\n </span>\n )}\n </>\n )}\n </div>\n\n <div className=\"bg-card border overflow-hidden rounded-lg\">\n <Table>\n <TableHeader className=\"bg-secondary\">\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n return (\n <TableHead key={header.id}>\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isPending ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n <div className=\"text-muted-foreground\">Loading ${schema.label}...</div>\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n <div className=\"text-destructive\">Error loading ${schema.label}: {error.message}</div>\n </TableCell>\n </TableRow>\n ) : table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n No ${schema.label} found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">Rows per page</span>\n <Select\n value={pageSize === -1 ? 'all' : String(pageSize)}\n onValueChange={handlePageSizeChange}\n >\n <SelectTrigger className=\"w-[100px] h-8\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PAGE_SIZE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n Previous\n </Button>\n <div className=\"text-sm text-muted-foreground\">\n Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount() || 1}\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(tableFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, tableFileName)]\n }\n}\n","/**\n * Pipeline orchestrator — runs all 12 entity generation steps in sequence\n */\n\nimport type { BetterstartConfig } from '../config/types.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { generateActions, generateSingleActions } from './actions/index.js'\nimport { generateCache } from './cache.js'\nimport { generateColumns } from './columns/index.js'\nimport { generateCreatePage } from './create-page.js'\nimport { generateDatabase } from './database.js'\nimport { generateEditPage } from './edit-page.js'\nimport { generateForm, generateSingleForm } from './form/index.js'\nimport { generateHook, generateSingleHook } from './hook.js'\nimport { updateNavigation } from './navigation.js'\nimport { generatePage } from './page.js'\nimport { generatePageContent } from './page-content.js'\nimport { generateSinglePage } from './single-page.js'\nimport { generateTable } from './table.js'\n\nexport interface PipelineResult {\n success: boolean\n files: string[]\n errors: string[]\n}\n\n/**\n * Resolve output directories from config paths\n */\nfunction resolvePaths(config: BetterstartConfig) {\n const cms = config.paths?.cms ?? './cms'\n const pages = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n const schemas = config.paths?.schemas ?? './cms/schemas'\n\n return {\n cmsDir: cms,\n pagesDir: pages,\n schemasDir: schemas,\n dbSchemaDir: `${cms}/db/schema.ts`,\n actionsDir: `${cms}/lib/actions`,\n hooksDir: `${cms}/hooks`\n }\n}\n\n/**\n * Run the full 12-step entity generation pipeline\n */\nexport function runEntityPipeline(\n schema: Schema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): PipelineResult {\n const paths = resolvePaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema',\n run: () => generateDatabase(schema, cwd, paths.dbSchemaDir, options).files\n },\n {\n name: 'Server actions',\n run: () =>\n generateActions(schema, cwd, paths.actionsDir, {\n force: options.force,\n schemasDir: paths.schemasDir\n }).files\n },\n {\n name: 'React Query hook',\n run: () => generateHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Column definitions',\n run: () => generateColumns(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Table component',\n run: () => generateTable(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Page content',\n run: () => generatePageContent(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Page (server)',\n run: () => generatePage(schema, cwd, paths.pagesDir, options).files\n }\n ]\n\n // Steps 8-10 are conditional on schema.actions\n if (schema.actions?.create || schema.actions?.edit) {\n steps.push({\n name: 'Form',\n run: () => generateForm(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n if (schema.actions?.create) {\n steps.push({\n name: 'Create page',\n run: () => generateCreatePage(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n if (schema.actions?.edit) {\n steps.push({\n name: 'Edit page',\n run: () => generateEditPage(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n // Steps 11-12 always run\n steps.push(\n {\n name: 'Navigation',\n run: () => updateNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Cache module',\n run: () => generateCache(schema, cwd, paths.cmsDir, options).files\n }\n )\n\n // Execute each step\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return {\n success: errors.length === 0,\n files,\n errors\n }\n}\n\n/**\n * Run the 7-step single (singleton) generation pipeline\n */\nexport function runSinglePipeline(\n schema: Schema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): PipelineResult {\n const paths = resolvePaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema',\n run: () => generateDatabase(schema, cwd, paths.dbSchemaDir, options).files\n },\n {\n name: 'Server actions',\n run: () =>\n generateSingleActions(schema, cwd, paths.actionsDir, { force: options.force }).files\n },\n {\n name: 'React Query hook',\n run: () => generateSingleHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Form',\n run: () => generateSingleForm(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Single page',\n run: () => generateSinglePage(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Navigation',\n run: () => updateNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Cache module',\n run: () => generateCache(schema, cwd, paths.cmsDir, options).files\n }\n ]\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return {\n success: errors.length === 0,\n files,\n errors\n }\n}\n\n// Re-export individual generators for direct use\nexport { generateActions, generateSingleActions } from './actions/index.js'\nexport { generateCache } from './cache.js'\nexport { generateColumns } from './columns/index.js'\nexport { generateCreatePage } from './create-page.js'\nexport { generateDatabase } from './database.js'\nexport { generateEditPage } from './edit-page.js'\nexport { generateForm, generateSingleForm } from './form/index.js'\nexport { generateHook, generateSingleHook } from './hook.js'\nexport { updateNavigation } from './navigation.js'\nexport { generatePage } from './page.js'\nexport { generatePageContent } from './page-content.js'\nexport { generateSinglePage } from './single-page.js'\nexport { generateTable } from './table.js'\n","/**\n * Post-generation tasks: auto db:push + lint:fix\n */\n\nimport { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { PackageManager } from '../utils/package-manager.js'\nimport { detectPackageManager } from '../utils/package-manager.js'\n\n/**\n * Load .env.local and set variables on process.env (if not already set)\n */\nfunction loadEnvFile(cwd: string): void {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return\n\n const content = fs.readFileSync(envPath, 'utf-8')\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n\n const eqIdx = trimmed.indexOf('=')\n if (eqIdx === -1) continue\n\n const key = trimmed.slice(0, eqIdx).trim()\n let value = trimmed.slice(eqIdx + 1).trim()\n\n // Strip surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1)\n }\n\n // Strip inline comments\n const commentIdx = value.indexOf(' #')\n if (commentIdx !== -1) {\n value = value.slice(0, commentIdx).trim()\n }\n\n if (!process.env[key]) {\n process.env[key] = value\n }\n }\n}\n\nfunction runPmScript(pm: PackageManager, script: string, cwd: string): boolean {\n const args = pm === 'bun' ? ['run', script] : [script]\n try {\n execFileSync(pm, args, { cwd, stdio: 'pipe' })\n return true\n } catch {\n return false\n }\n}\n\nfunction hasPkgScript(cwd: string, script: string): boolean {\n const pkgPath = path.join(cwd, 'package.json')\n if (!fs.existsSync(pkgPath)) return false\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>\n const scripts = pkg.scripts as Record<string, unknown> | undefined\n return !!scripts?.[script]\n } catch {\n return false\n }\n}\n\nexport interface PostGenerateOptions {\n skipMigration?: boolean\n}\n\nexport interface PostGenerateResult {\n dbPush: 'success' | 'skipped' | 'no-db-url' | 'failed'\n lintFix: 'success' | 'skipped' | 'failed'\n}\n\n/**\n * Run post-generation tasks: db:push and lint:fix\n */\nexport function runPostGenerate(\n cwd: string,\n schemaName: string,\n options: PostGenerateOptions = {}\n): PostGenerateResult {\n const pm = detectPackageManager(cwd)\n const result: PostGenerateResult = {\n dbPush: 'skipped',\n lintFix: 'skipped'\n }\n\n // 1. Database push\n if (!options.skipMigration) {\n loadEnvFile(cwd)\n\n const dbUrl = process.env.BETTERSTART_DATABASE_URL || process.env.DATABASE_URL\n\n if (!dbUrl) {\n result.dbPush = 'no-db-url'\n console.log('\\n Database: skipped (no DATABASE_URL configured)')\n console.log(' To sync later: run db:push after setting BETTERSTART_DATABASE_URL')\n } else if (hasPkgScript(cwd, 'db:push')) {\n console.log('\\n Running db:push...')\n const ok = runPmScript(pm, 'db:push', cwd)\n result.dbPush = ok ? 'success' : 'failed'\n console.log(ok ? ' Database schema synced' : ' Database push failed (run db:push manually)')\n } else {\n // Try running drizzle-kit push directly using project-local binary\n console.log('\\n Running drizzle-kit push...')\n const drizzleBin = path.join(cwd, 'node_modules', '.bin', 'drizzle-kit')\n try {\n execFileSync(drizzleBin, ['push', '--force'], { cwd, stdio: 'inherit' })\n result.dbPush = 'success'\n console.log(' Database schema synced')\n } catch {\n result.dbPush = 'failed'\n console.log(' Database push failed (run drizzle-kit push manually)')\n }\n }\n } else {\n console.log('\\n Database: skipped (--skip-migration)')\n }\n\n // 2. Lint fix\n if (hasPkgScript(cwd, 'lint:fix')) {\n console.log(' Running lint:fix...')\n const ok = runPmScript(pm, 'lint:fix', cwd)\n result.lintFix = ok ? 'success' : 'failed'\n console.log(ok ? ' Code formatted' : ' Lint fix had issues (run lint:fix manually)')\n } else {\n // Try biome directly using project-local binary\n const biomeBin = path.join(cwd, 'node_modules', '.bin', 'biome')\n try {\n execFileSync(biomeBin, ['check', '--write', '.'], { cwd, stdio: 'pipe' })\n result.lintFix = 'success'\n console.log(' Code formatted with Biome')\n } catch {\n result.lintFix = 'skipped'\n }\n }\n\n // Next steps\n console.log('\\n Next steps:')\n console.log(' 1. Review the generated files')\n if (options.skipMigration || result.dbPush !== 'success') {\n console.log(' 2. Run database migration: db:push')\n console.log(` 3. Start the dev server and visit /cms/${schemaName}`)\n } else {\n console.log(` 2. Start the dev server and visit /cms/${schemaName}`)\n }\n\n return result\n}\n","import { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\nconst LOCKFILE_MAP: Record<string, PackageManager> = {\n 'pnpm-lock.yaml': 'pnpm',\n 'package-lock.json': 'npm',\n 'yarn.lock': 'yarn',\n 'bun.lockb': 'bun',\n 'bun.lock': 'bun'\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n // Walk up the directory tree to find lockfiles (handles monorepos)\n let dir = path.resolve(cwd)\n const root = path.parse(dir).root\n while (dir !== root) {\n for (const [lockfile, pm] of Object.entries(LOCKFILE_MAP)) {\n if (fs.existsSync(path.join(dir, lockfile))) {\n return pm\n }\n }\n // Check packageManager field in package.json at this level\n const pkgPath = path.join(dir, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>\n if (typeof pkg.packageManager === 'string') {\n const name = pkg.packageManager.split('@')[0]\n if (name === 'pnpm' || name === 'npm' || name === 'yarn' || name === 'bun') {\n return name\n }\n }\n } catch {\n // ignore parse errors\n }\n }\n dir = path.dirname(dir)\n }\n\n return 'npm'\n}\n\nexport function installCommand(pm: PackageManager): string {\n return pm === 'yarn' ? 'yarn' : `${pm} install`\n}\n\nexport function addCommand(pm: PackageManager, deps: string[], dev = false): string {\n const devFlag = dev ? (pm === 'yarn' ? '--dev' : '-D') : ''\n\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${devFlag} ${deps.join(' ')}`.trim()\n case 'yarn':\n return `yarn add ${devFlag} ${deps.join(' ')}`.trim()\n case 'bun':\n return `bun add ${devFlag} ${deps.join(' ')}`.trim()\n default:\n return `npm install ${devFlag} ${deps.join(' ')}`.trim()\n }\n}\n\nexport function runCommand(pm: PackageManager, script: string): string {\n switch (pm) {\n case 'pnpm':\n return `pnpm ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'bun':\n return `bun run ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function execPm(pm: PackageManager, args: string[], cwd: string): void {\n execFileSync(pm, args, { cwd, stdio: 'inherit' })\n}\n\n/**\n * Returns the binary + leading args to run `create-next-app` via the given package manager.\n * Using the native PM avoids nested-npx issues (e.g. running inside `npx @betterstart/cli`).\n */\nexport function createNextAppCommand(pm: PackageManager): { bin: string; prefix: string[] } {\n switch (pm) {\n case 'pnpm':\n return { bin: 'pnpm', prefix: ['create', 'next-app@latest'] }\n case 'yarn':\n return { bin: 'yarn', prefix: ['create', 'next-app@latest'] }\n case 'bun':\n return { bin: 'bunx', prefix: ['create-next-app@latest'] }\n default:\n return { bin: 'npx', prefix: ['create-next-app@latest'] }\n }\n}\n","import { execFileSync, spawn } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\nimport { getDefaultConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport { promptDatabase } from '../init/prompts/database.js'\nimport { promptFeatures } from '../init/prompts/features.js'\nimport { promptProject } from '../init/prompts/project.js'\nimport { scaffoldApiRoutes } from '../init/scaffolders/api-routes.js'\nimport { scaffoldAuth } from '../init/scaffolders/auth.js'\nimport { regenerateCmsDoc, scaffoldBase } from '../init/scaffolders/base.js'\nimport { scaffoldBiome } from '../init/scaffolders/biome.js'\nimport { scaffoldComponents } from '../init/scaffolders/components.js'\nimport { scaffoldDatabase } from '../init/scaffolders/database.js'\nimport { installDependenciesAsync } from '../init/scaffolders/dependencies.js'\nimport { detectDevPort, scaffoldEnv } from '../init/scaffolders/env.js'\nimport { scaffoldLayout } from '../init/scaffolders/layout.js'\nimport { scaffoldPreset } from '../init/scaffolders/preset.js'\nimport { scaffoldTailwind } from '../init/scaffolders/tailwind.js'\nimport { scaffoldTsconfig } from '../init/scaffolders/tsconfig.js'\nimport { detectProject } from '../utils/detect.js'\nimport { createNextAppCommand, detectPackageManager, runCommand } from '../utils/package-manager.js'\nimport { buildSeedScript } from './seed.js'\n\nexport const initCommand = new Command('init')\n .description('Scaffold CMS into a new or existing Next.js project')\n .argument('[name]', 'Project name (creates new directory if fresh project)')\n .option('--preset <preset>', 'Starter preset: blank, blog, or full', 'blog')\n .option('-y, --yes', 'Skip all prompts (accept defaults)')\n .option(\n '--database-url <url>',\n 'PostgreSQL database connection string (postgres:// or postgresql://)'\n )\n .option('--force', 'Overwrite all existing CMS files (nuclear option)')\n .action(\n async (\n name: string | undefined,\n options: { preset: string; yes?: boolean; databaseUrl?: string; force?: boolean }\n ) => {\n p.intro(pc.bgCyan(pc.black(' BetterStart CMS ')))\n\n let cwd = process.cwd()\n let project = detectProject(cwd)\n let pm = detectPackageManager(cwd)\n let isFreshProject = false\n\n // Determine srcDir\n let srcDir: boolean\n if (project.isExisting) {\n p.log.info(`Next.js project detected ${pc.dim('·')} ${pc.cyan(pm)}`)\n srcDir = project.hasSrcDir\n\n if (!project.hasTypeScript) {\n p.log.error('TypeScript is required. Please add a tsconfig.json first.')\n process.exit(1)\n }\n\n if (options.force) {\n // Nuclear option: wipe all CMS-owned directories and root-level files\n const nukeDirs = ['cms', 'app/(cms)', 'src/app/(cms)']\n const nukeFiles = ['cms.config.ts', 'CMS.md', 'drizzle.config.ts']\n let nuked = 0\n for (const dir of nukeDirs) {\n const fullPath = path.resolve(cwd, dir)\n if (fs.existsSync(fullPath)) {\n fs.rmSync(fullPath, { recursive: true, force: true })\n nuked++\n }\n }\n for (const file of nukeFiles) {\n const fullPath = path.resolve(cwd, file)\n if (fs.existsSync(fullPath)) {\n fs.unlinkSync(fullPath)\n nuked++\n }\n }\n if (nuked > 0) {\n p.log.warn(`${pc.yellow('Force mode:')} removed ${nuked} existing CMS paths`)\n }\n // Re-detect project after wipe\n project = detectProject(cwd)\n } else if (project.conflicts.length > 0) {\n const conflictLines = project.conflicts.map((c) => `${pc.yellow('▲')} ${c}`)\n conflictLines.push(\n '',\n pc.dim('Existing files will not be overwritten.'),\n pc.dim(`Use ${pc.bold('--force')} to remove existing CMS files before scaffolding.`)\n )\n p.note(conflictLines.join('\\n'), pc.yellow('Conflicts'))\n if (!options.yes) {\n const proceed = await p.confirm({\n message: 'Continue anyway?',\n initialValue: true\n })\n if (p.isCancel(proceed) || !proceed) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n }\n }\n } else {\n p.log.info('No Next.js project found — fresh project mode')\n const projectPrompt = await promptProject(name)\n srcDir = projectPrompt.useSrcDir\n\n // Ask for preferred package manager\n if (!options.yes) {\n const pmChoice = await p.select({\n message: 'Which package manager do you want to use?',\n options: [\n { value: 'pnpm' as const, label: 'pnpm', hint: 'recommended' },\n { value: 'npm' as const, label: 'npm' },\n { value: 'yarn' as const, label: 'yarn' },\n { value: 'bun' as const, label: 'bun' }\n ]\n })\n if (p.isCancel(pmChoice)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n pm = pmChoice\n }\n\n // Run create-next-app using the selected package manager's native command\n // to avoid nested-npx issues (e.g. when running via `npx @betterstart/cli`)\n const displayName =\n projectPrompt.projectName === '.' ? path.basename(cwd) : projectPrompt.projectName\n\n const { bin, prefix } = createNextAppCommand(pm)\n const cnaArgs = [\n ...prefix,\n projectPrompt.projectName,\n '--yes',\n '--typescript',\n '--tailwind',\n '--app',\n '--turbopack',\n '--biome',\n '--react-compiler',\n `--use-${pm}`\n ]\n if (srcDir) cnaArgs.push('--src-dir')\n else cnaArgs.push('--no-src-dir')\n\n p.log.step(`Creating Next.js app: ${pc.cyan(displayName)}`)\n\n try {\n execFileSync(bin, cnaArgs, {\n cwd,\n stdio: 'inherit',\n timeout: 120_000\n })\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'create-next-app failed')\n p.log.info(\n `You can create the project manually:\\n ${pc.cyan(`npx create-next-app@latest ${projectPrompt.projectName} --typescript --tailwind --app`)}\\n Then run ${pc.cyan('betterstart init')} inside it.`\n )\n process.exit(1)\n }\n\n // Move into the new project directory\n cwd = path.resolve(cwd, projectPrompt.projectName)\n\n // Verify the project was actually created\n const hasPackageJson = fs.existsSync(path.join(cwd, 'package.json'))\n const hasNextConfig = ['next.config.ts', 'next.config.js', 'next.config.mjs'].some((f) =>\n fs.existsSync(path.join(cwd, f))\n )\n\n if (!hasPackageJson || !hasNextConfig) {\n p.log.error(\n 'create-next-app completed but the project was not created. This can happen with nested npx calls.'\n )\n const manualCmd = `npx create-next-app@latest ${projectPrompt.projectName} --typescript --tailwind --app`\n p.log.info(\n `Create the project manually:\\n ${pc.cyan(manualCmd)}\\n Then run ${pc.cyan('betterstart init')} inside it.`\n )\n process.exit(1)\n }\n\n p.log.success(`Created ${displayName} Next.js project`)\n project = detectProject(cwd)\n isFreshProject = true\n }\n\n // Feature prompts\n const features = options.yes\n ? { includeEmail: true, preset: options.preset as 'blank' | 'blog' | 'full' }\n : await promptFeatures(options.preset)\n\n // Database URL — check existing .env.local first, then prompt if needed\n let databaseUrl: string | undefined\n const existingDbUrl = readExistingDbUrl(cwd)\n\n if (options.yes) {\n // Non-interactive mode: --database-url flag > existing env > placeholder\n if (options.databaseUrl) {\n if (!isValidDbUrl(options.databaseUrl)) {\n p.log.error(\n `Invalid database URL. Must start with ${pc.cyan('postgres://')} or ${pc.cyan('postgresql://')}`\n )\n process.exit(1)\n }\n databaseUrl = options.databaseUrl\n } else if (existingDbUrl) {\n databaseUrl = existingDbUrl\n }\n // else: no flag, no existing → use placeholder (databaseUrl stays undefined)\n } else if (existingDbUrl) {\n // Interactive mode but a valid URL already exists — skip the prompt\n const masked = maskDbUrl(existingDbUrl)\n p.log.info(`Using existing database URL from .env.local ${pc.dim(`(${masked})`)}`)\n databaseUrl = existingDbUrl\n } else {\n const dbResult = await promptDatabase()\n databaseUrl = dbResult.url\n }\n\n // Build config\n const config: BetterstartConfig = {\n ...getDefaultConfig(srcDir),\n features: { email: features.includeEmail }\n }\n\n // Run scaffolders — group fast steps under one spinner, then show results in a note box\n interface ScaffoldResult {\n label: string\n result: string\n }\n const results: ScaffoldResult[] = []\n const s = p.spinner()\n\n s.start('Directory structure')\n\n const baseFiles = scaffoldBase({ cwd, config })\n results.push({ label: 'Directory structure', result: `${baseFiles.length} files` })\n\n s.message('TypeScript aliases')\n const tsResult = scaffoldTsconfig(cwd)\n results.push({\n label: 'TypeScript aliases',\n result: tsResult.added.length > 0 ? `${tsResult.added.length} paths` : 'already set'\n })\n\n s.message('Tailwind CSS')\n const twResult = scaffoldTailwind(cwd, srcDir)\n results.push({\n label: 'Tailwind CSS',\n result: twResult.appended ? 'updated' : twResult.file ? 'already set' : 'no CSS file'\n })\n\n s.message('Environment variables')\n const envResult = scaffoldEnv(cwd, { includeEmail: features.includeEmail, databaseUrl })\n const envCount = envResult.added.length + envResult.updated.length\n results.push({\n label: 'Environment variables',\n result: envCount > 0 ? `${envCount} vars` : 'already set'\n })\n\n s.message('Database')\n const dbFiles = scaffoldDatabase({ cwd, config })\n results.push({ label: 'Database', result: `${dbFiles.length} files` })\n\n s.message('Authentication')\n const authFiles = scaffoldAuth({ cwd, config })\n results.push({ label: 'Authentication', result: `${authFiles.length} files` })\n\n s.message('Components')\n const compFiles = scaffoldComponents({ cwd, config })\n results.push({ label: 'Components', result: `${compFiles.length} files` })\n\n s.message('Pages & layouts')\n const layoutFiles = scaffoldLayout({ cwd, config })\n results.push({ label: 'Pages & layouts', result: `${layoutFiles.length} files` })\n\n s.message('API routes')\n const apiFiles = scaffoldApiRoutes({ cwd, config })\n results.push({ label: 'API routes', result: `${apiFiles.length} routes` })\n\n s.message('Linter')\n let linterResult: string\n if (project.linter.type === 'none') {\n const biomeResult = scaffoldBiome(cwd, project.linter)\n linterResult = biomeResult.installed ? 'biome (new)' : 'none'\n } else {\n linterResult = project.linter.type\n }\n results.push({ label: 'Linter', result: linterResult })\n\n // Build the note content before stopping the spinner\n const maxLabel = Math.max(...results.map((r) => r.label.length))\n const noteLines = results.map((r) => {\n const padded = r.label.padEnd(maxLabel + 3)\n return `${pc.green('✓')} ${padded}${pc.dim(r.result)}`\n })\n\n // Stop spinner quietly and erase the empty stop line, then show results card\n s.stop('')\n process.stdout.write('\\x1B[2A\\x1B[J')\n p.note(noteLines.join('\\n'), 'Scaffolded CMS')\n\n // If drizzle.config.ts already existed (wasn't created), offer to update it\n const drizzleConfigPath = path.join(cwd, 'drizzle.config.ts')\n if (!dbFiles.includes('drizzle.config.ts') && fs.existsSync(drizzleConfigPath)) {\n if (options.force) {\n const { readTemplate } = await import('../init/templates/reader.js')\n fs.writeFileSync(drizzleConfigPath, readTemplate('drizzle.config.ts'), 'utf-8')\n p.log.success('Updated drizzle.config.ts')\n } else if (!options.yes) {\n const overwrite = await p.confirm({\n message: 'drizzle.config.ts already exists. Overwrite with latest version?',\n initialValue: true\n })\n if (!p.isCancel(overwrite) && overwrite) {\n const { readTemplate } = await import('../init/templates/reader.js')\n fs.writeFileSync(drizzleConfigPath, readTemplate('drizzle.config.ts'), 'utf-8')\n p.log.success('Updated drizzle.config.ts')\n }\n }\n }\n\n // Install dependencies (async so spinner can animate)\n s.start('Installing dependencies (this may take a minute)')\n const depsResult = await installDependenciesAsync({\n cwd,\n pm,\n includeEmail: features.includeEmail,\n includeBiome: project.linter.type === 'none'\n })\n let depsInstalled = false\n if (depsResult.success) {\n s.stop('')\n depsInstalled = true\n } else {\n s.stop('Failed to install dependencies')\n p.log.warning(depsResult.error ?? 'Unknown error')\n p.log.info(\n `You can install them manually:\\n ${pc.cyan(`${pm} add ${depsResult.coreDeps.join(' ')}`)}\\n ${pc.cyan(`${pm} add -D ${depsResult.devDeps.join(' ')}`)}`\n )\n }\n\n // Apply preset schemas + run entity generation + regenerate CMS.md\n if (depsInstalled) {\n process.stdout.write('\\x1B[2A\\x1B[J')\n }\n s.start(`Applying ${features.preset} preset`)\n const presetResult = scaffoldPreset({ cwd, config, preset: features.preset })\n // Regenerate CMS.md with full documentation\n {\n const entityNames: string[] = []\n const formNames: string[] = []\n const schemasDir = path.join(cwd, config.paths.schemas)\n const formsDir = path.join(schemasDir, 'forms')\n if (fs.existsSync(schemasDir)) {\n for (const f of fs.readdirSync(schemasDir)) {\n if (f.endsWith('.json')) entityNames.push(f.replace('.json', ''))\n }\n }\n if (fs.existsSync(formsDir)) {\n for (const f of fs.readdirSync(formsDir)) {\n if (f.endsWith('.json')) formNames.push(f.replace('.json', ''))\n }\n }\n regenerateCmsDoc(cwd, config, {\n preset: features.preset,\n schemas: entityNames,\n forms: formNames\n })\n }\n s.stop('')\n process.stdout.write('\\x1B[2A\\x1B[J')\n\n // Build combined note for deps + preset\n const installLines: string[] = []\n if (depsInstalled) {\n installLines.push(\n `${pc.green('✓')} Dependencies ${pc.dim(`${depsResult.coreDeps.length} deps + ${depsResult.devDeps.length} dev deps`)}`\n )\n }\n if (presetResult.errors.length > 0) {\n installLines.push(\n `${pc.yellow('▲')} Preset ${pc.dim(`${features.preset} — ${presetResult.errors.length} warning(s)`)}`\n )\n for (const err of presetResult.errors) {\n installLines.push(` ${pc.dim(err)}`)\n }\n } else {\n installLines.push(\n `${pc.green('✓')} Preset ${pc.dim(`${features.preset} — ${presetResult.schemas.length} schemas, ${presetResult.generatedFiles.length} files`)}`\n )\n }\n p.note(installLines.join('\\n'), 'Installed')\n\n // Push database schema if env var is configured (after preset so entity tables are included)\n let dbPushed = false\n if (depsResult.success && hasDbUrl(cwd)) {\n s.start('Pushing database schema (drizzle-kit push)')\n const pushResult = await runDrizzlePush(cwd)\n if (pushResult.success) {\n s.stop(`${pc.green('✓')} Database schema pushed`)\n dbPushed = true\n } else {\n s.stop('Database push failed')\n p.log.warning(pushResult.error ?? 'Unknown error')\n p.log.info(`You can run it manually: ${pc.cyan('npx drizzle-kit push')}`)\n }\n }\n\n // Auto-seed admin user (only when db push succeeded and interactive mode)\n let seedEmail: string | undefined\n let seedPassword: string | undefined\n let seedSuccess = false\n\n if (dbPushed && !options.yes) {\n p.note(pc.dim('Create your first admin user to access the CMS.'), 'Admin account')\n\n const credentials = await p.group(\n {\n email: () =>\n p.text({\n message: 'Admin email',\n placeholder: 'admin@example.com',\n validate: (v) => {\n if (!v || !v.includes('@')) return 'Please enter a valid email'\n }\n }),\n password: () =>\n p.password({\n message: 'Admin password',\n validate: (v) => {\n if (!v || v.length < 8) return 'Password must be at least 8 characters'\n }\n })\n },\n {\n onCancel: () => {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n }\n )\n\n seedEmail = credentials.email\n seedPassword = credentials.password\n\n s.start('Creating admin user')\n let seedResult = await runSeed(\n cwd,\n config.paths?.cms ?? './cms',\n credentials.email,\n credentials.password\n )\n\n if (seedResult.existingUser) {\n s.stop(`${pc.yellow('▲')} Admin user already exists (${seedResult.existingUser})`)\n const replace = await p.confirm({\n message: 'Replace existing admin user?',\n initialValue: false\n })\n if (!p.isCancel(replace) && replace) {\n s.start('Replacing admin user')\n seedResult = await runSeed(\n cwd,\n config.paths?.cms ?? './cms',\n credentials.email,\n credentials.password,\n true\n )\n } else {\n seedSuccess = true\n }\n }\n\n if (seedResult.success) {\n s.stop(`${pc.green('✓')} Admin user created`)\n seedSuccess = true\n } else if (!seedSuccess && seedResult.error) {\n s.stop(`${pc.red('✗')} Failed to create admin user`)\n p.note(\n `${pc.red(seedResult.error)}\\n\\nRun manually: ${pc.cyan('npx betterstart seed')}`,\n pc.red('Seed failed')\n )\n }\n }\n\n // Git init + commit for fresh projects\n if (isFreshProject) {\n s.start('Creating initial git commit')\n try {\n execFileSync('git', ['init'], { cwd, stdio: 'pipe' })\n execFileSync('git', ['add', '.'], { cwd, stdio: 'pipe' })\n execFileSync('git', ['commit', '-m', 'Initial commit from BetterStart'], {\n cwd,\n stdio: 'pipe'\n })\n s.stop('Created initial git commit')\n } catch {\n s.stop('Git commit skipped')\n }\n }\n\n const totalFiles =\n baseFiles.length +\n dbFiles.length +\n authFiles.length +\n compFiles.length +\n layoutFiles.length +\n apiFiles.length\n\n // Summary\n const summaryLines: string[] = [\n `Preset: ${pc.cyan(features.preset)}`,\n `Files created: ${pc.cyan(String(totalFiles))}`,\n `Env vars: ${envResult.added.length} added, ${envResult.skipped.length} skipped`\n ]\n\n if (seedSuccess && seedEmail && seedPassword) {\n summaryLines.push(\n '',\n `Admin: ${pc.cyan(seedEmail)}`,\n `Password: ${pc.cyan(seedPassword)}`,\n `CMS: ${pc.cyan(`http://localhost:${detectDevPort(cwd)}/cms/login`)}`\n )\n }\n\n // Next steps\n const nextSteps: string[] = []\n let step = 1\n const envStepLabel = databaseUrl\n ? `Fill in remaining values in ${pc.cyan('.env.local')}`\n : `Fill in values in ${pc.cyan('.env.local')}`\n nextSteps.push(` ${step++}. ${envStepLabel}`)\n if (!dbPushed) {\n nextSteps.push(` ${step++}. Run ${pc.cyan('npx drizzle-kit push')} to sync the database`)\n }\n if (!seedSuccess) {\n nextSteps.push(\n ` ${step++}. Run ${pc.cyan('npx betterstart seed')} to create an admin user`\n )\n }\n nextSteps.push(` ${step++}. Run ${pc.cyan('pnpm run dev')} to start the development server`)\n nextSteps.push(\n ` ${step++}. Run ${pc.cyan('npx betterstart generate <schema>')} to create content types`\n )\n\n summaryLines.push('', 'Next steps:', ...nextSteps)\n\n p.note(summaryLines.join('\\n'), 'CMS scaffolded successfully')\n\n // Offer to start the dev server (interactive mode only)\n if (!options.yes) {\n const devCmd = runCommand(pm, 'dev')\n const startDev = await p.confirm({\n message: 'Start the development server?',\n initialValue: true\n })\n\n if (!p.isCancel(startDev) && startDev) {\n p.outro(`Starting ${pc.cyan(devCmd)}...`)\n const [bin, ...args] = devCmd.split(' ')\n spawn(bin, args, { cwd, stdio: 'inherit' })\n return\n }\n }\n\n p.outro('Done!')\n }\n )\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Validate a database connection URL */\nfunction isValidDbUrl(url: string): boolean {\n return url.startsWith('postgres://') || url.startsWith('postgresql://')\n}\n\n/** Read BETTERSTART_DATABASE_URL from .env.local, returning the value if it's a real URL. */\nfunction readExistingDbUrl(cwd: string): string | undefined {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return undefined\n const content = fs.readFileSync(envPath, 'utf-8')\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.startsWith('#') || !trimmed.includes('=')) continue\n const [key, ...rest] = trimmed.split('=')\n if (key?.trim() === 'BETTERSTART_DATABASE_URL') {\n const val = rest\n .join('=')\n .replace(/^['\"]|['\"]$/g, '')\n .trim()\n if (\n val.length > 0 &&\n !val.startsWith('your_') &&\n val !== 'postgresql://...' &&\n isValidDbUrl(val)\n ) {\n return val\n }\n }\n }\n return undefined\n}\n\n/** Mask a database URL for display: show host only. */\nfunction maskDbUrl(url: string): string {\n try {\n const parsed = new URL(url)\n return `${parsed.protocol}//${parsed.host}/***`\n } catch {\n return 'postgres://***'\n }\n}\n\n/** Check if BETTERSTART_DATABASE_URL is set in .env.local */\nfunction hasDbUrl(cwd: string): boolean {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return false\n const content = fs.readFileSync(envPath, 'utf-8')\n // Check the var exists and has a non-placeholder value\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.startsWith('#') || !trimmed.includes('=')) continue\n const [key, ...rest] = trimmed.split('=')\n if (key?.trim() === 'BETTERSTART_DATABASE_URL') {\n const val = rest.join('=').trim()\n const unquoted = val.replace(/^['\"]|['\"]$/g, '')\n return unquoted.length > 0 && !unquoted.startsWith('your_') && unquoted !== 'postgresql://...'\n }\n }\n return false\n}\n\ninterface SeedResult {\n success: boolean\n error: string | null\n existingUser?: string\n}\n\n/** Write seed script, run it with tsx, clean up. Returns success/error. */\nfunction runSeed(\n cwd: string,\n cmsDir: string,\n email: string,\n password: string,\n overwrite = false\n): Promise<SeedResult> {\n const scriptsDir = path.join(cwd, cmsDir, 'scripts')\n const seedPath = path.join(scriptsDir, 'seed.ts')\n\n if (!fs.existsSync(scriptsDir)) {\n fs.mkdirSync(scriptsDir, { recursive: true })\n }\n fs.writeFileSync(seedPath, buildSeedScript(), 'utf-8')\n\n const cleanup = () => {\n try {\n fs.unlinkSync(seedPath)\n if (fs.existsSync(scriptsDir) && fs.readdirSync(scriptsDir).length === 0) {\n fs.rmdirSync(scriptsDir)\n }\n } catch {\n // Not critical\n }\n }\n\n return new Promise((resolve) => {\n const tsxBin = path.join(cwd, 'node_modules', '.bin', 'tsx')\n const child = spawn(tsxBin, [seedPath], {\n cwd,\n stdio: 'pipe',\n env: {\n ...process.env,\n SEED_EMAIL: email,\n SEED_PASSWORD: password,\n SEED_NAME: 'Admin',\n ...(overwrite ? { SEED_OVERWRITE: 'true' } : {})\n }\n })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString()\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n const timeout = setTimeout(() => {\n child.kill()\n cleanup()\n resolve({ success: false, error: 'Seed timed out after 30 seconds' })\n }, 30_000)\n child.on('close', (code) => {\n clearTimeout(timeout)\n cleanup()\n if (code === 0) {\n resolve({ success: true, error: null })\n } else if (code === 2) {\n // Exit code 2 = user already exists\n const name = stdout.match(/EXISTING_USER:(.+)/)?.[1]?.trim()\n resolve({ success: false, error: null, existingUser: name ?? email })\n } else {\n resolve({ success: false, error: parseSeedError(stdout, stderr) })\n }\n })\n child.on('error', (err) => {\n clearTimeout(timeout)\n cleanup()\n resolve({ success: false, error: parseSeedError('', err.message) })\n })\n })\n}\n\n/** Extract a human-readable error from seed script output */\nfunction parseSeedError(stdout: string, stderr: string): string {\n // Check for common patterns in stderr/stdout\n const combined = `${stdout}\\n${stderr}`\n\n // \"Seed failed: <message>\" from the catch handler\n const seedFailed = combined.match(/Seed failed:\\s*(.+)/)?.[1]?.trim()\n if (seedFailed) return seedFailed\n\n // \"Failed to create user\" from auth API failure\n if (combined.includes('Failed to create user')) return 'Auth API failed to create user'\n\n // Connection errors\n if (combined.includes('ECONNREFUSED') || combined.includes('connection refused'))\n return 'Could not connect to database'\n if (combined.includes('BETTERSTART_DATABASE_URL')) return 'Database URL is missing or invalid'\n if (combined.includes('password authentication failed'))\n return 'Database authentication failed — check your connection string'\n if (combined.includes('does not exist') && combined.includes('relation'))\n return 'Database tables not found — run npx drizzle-kit push first'\n if (combined.includes('MODULE_NOT_FOUND') || combined.includes('Cannot find module'))\n return 'Missing dependencies — run your package manager install first'\n\n // Fall back to first meaningful line of stderr\n const firstLine = stderr\n .split('\\n')\n .map((l) => l.trim())\n .find((l) => l.length > 0 && !l.startsWith('at ') && !l.startsWith('node:'))\n if (firstLine) return firstLine\n\n return 'Unknown error — run npx betterstart seed for details'\n}\n\n/** Run drizzle-kit push to sync the database schema */\nfunction runDrizzlePush(cwd: string): Promise<{ success: boolean; error: string | null }> {\n return new Promise((resolve) => {\n const drizzleBin = path.join(cwd, 'node_modules', '.bin', 'drizzle-kit')\n const child = spawn(drizzleBin, ['push', '--force'], {\n cwd,\n stdio: 'pipe',\n env: { ...process.env }\n })\n let stderr = ''\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n child.on('close', (code) => {\n if (code === 0) resolve({ success: true, error: null })\n else resolve({ success: false, error: stderr || `drizzle-kit push exited with code ${code}` })\n })\n child.on('error', (err) => {\n resolve({ success: false, error: err.message })\n })\n })\n}\n","import { execFileSync } from 'node:child_process'\n\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nexport interface DatabasePromptResult {\n url: string\n}\n\nconst VERCEL_NEON_URL = 'https://vercel.com/dashboard/integrations/checkout/neon'\n\n/**\n * Prompt the user to configure their database connection.\n *\n * Three paths:\n * 1. Vercel (Neon) — opens the integration page, then asks for the URL\n * 2. Supabase — \"coming soon\", loops back\n * 3. Manual — asks for the URL directly\n */\nexport async function promptDatabase(): Promise<DatabasePromptResult> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const choice = await p.select({\n message: 'How would you like to connect your database?',\n options: [\n {\n value: 'vercel-neon' as const,\n label: 'Vercel (Neon)',\n hint: 'opens browser to create a free Postgres database'\n },\n {\n value: 'supabase' as const,\n label: 'Supabase',\n hint: 'coming soon'\n },\n {\n value: 'manual' as const,\n label: 'Enter connection string manually'\n }\n ]\n })\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n if (choice === 'supabase') {\n p.log.warning('Supabase support is coming soon. Please choose another option.')\n continue\n }\n\n if (choice === 'vercel-neon') {\n openBrowser(VERCEL_NEON_URL)\n p.log.info(\n `Opening Vercel… Create a Neon Postgres database, then copy the ${pc.cyan('DATABASE_URL')} from the dashboard.`\n )\n }\n\n // Shared URL text prompt for both vercel-neon and manual\n const url = await promptConnectionString()\n return { url }\n }\n}\n\n/** Text prompt for the connection string with quote-stripping validation. */\nasync function promptConnectionString(): Promise<string> {\n const input = await p.text({\n message: 'Paste your database connection string',\n placeholder: 'postgres://user:pass@host/db',\n validate(val) {\n if (!val.trim()) {\n return 'A connection string is required to continue'\n }\n const stripped = val.replace(/^['\"]|['\"]$/g, '')\n if (!stripped.startsWith('postgres://') && !stripped.startsWith('postgresql://')) {\n return 'Must start with postgres:// or postgresql://'\n }\n }\n })\n\n if (p.isCancel(input)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n return (input as string).replace(/^['\"]|['\"]$/g, '').trim()\n}\n\n/** Best-effort browser open. Fails silently in headless / CI environments. */\nfunction openBrowser(url: string): void {\n try {\n const platform = process.platform\n if (platform === 'darwin') {\n execFileSync('open', [url], { stdio: 'ignore' })\n } else if (platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', url], { stdio: 'ignore' })\n } else {\n execFileSync('xdg-open', [url], { stdio: 'ignore' })\n }\n } catch {\n // Silently ignore — user can open the URL manually\n }\n}\n","import * as p from '@clack/prompts'\n\nexport type Preset = 'blank' | 'blog' | 'full'\n\nexport interface FeaturesPromptResult {\n includeEmail: true\n preset: Preset\n}\n\n/**\n * Prompt for preset selection.\n */\nexport async function promptFeatures(presetOverride?: string): Promise<FeaturesPromptResult> {\n let preset: Preset\n if (presetOverride && isValidPreset(presetOverride)) {\n preset = presetOverride\n } else {\n const selected = await p.select({\n message: 'Select a preset:',\n options: [\n { value: 'blog' as const, label: 'Blog', hint: 'Posts + Categories (recommended)' },\n { value: 'blank' as const, label: 'Blank', hint: 'CMS shell only, no content types' },\n { value: 'full' as const, label: 'Full', hint: 'Blog + Navigation + Contact form' }\n ],\n initialValue: 'blog' as const\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n preset = selected\n }\n\n return { includeEmail: true, preset }\n}\n\nfunction isValidPreset(value: string): value is Preset {\n return value === 'blank' || value === 'blog' || value === 'full'\n}\n","import * as p from '@clack/prompts'\n\nexport interface ProjectPromptResult {\n projectName: string\n useSrcDir: boolean\n}\n\n/**\n * Prompt for project name and src/ directory (fresh project only).\n */\nexport async function promptProject(defaultName?: string): Promise<ProjectPromptResult> {\n const projectName = await p.text({\n message: 'What is your project name?',\n placeholder: defaultName ?? 'my-app',\n defaultValue: defaultName ?? 'my-app',\n validate: (value) => {\n if (!value.trim()) return 'Project name is required'\n if (value.trim() === '.') return undefined\n if (!/^[a-z0-9_-]+$/i.test(value.trim())) {\n return 'Project name can only contain letters, numbers, hyphens, and underscores'\n }\n return undefined\n }\n })\n\n if (p.isCancel(projectName)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n const useSrcDir = await p.confirm({\n message: 'Use src/ directory?',\n initialValue: false\n })\n\n if (p.isCancel(useSrcDir)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n return { projectName: projectName.trim(), useSrcDir }\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface ApiRoutesScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create CMS API routes under /api/cms/.\n */\nexport function scaffoldApiRoutes({ cwd, config }: ApiRoutesScaffoldOptions): string[] {\n const created: string[] = []\n const apiDir = path.resolve(cwd, config.paths.api)\n\n function write(relPath: string, content: string): void {\n const fullPath = path.join(apiDir, relPath)\n ensureDir(path.dirname(fullPath))\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.api, relPath))\n }\n }\n\n // Better Auth catch-all: /api/cms/auth/[...all]/route.ts\n write(path.join('auth', '[...all]', 'route.ts'), readTemplate('api/auth-route.ts'))\n\n // Upload: /api/cms/upload/route.ts\n write(path.join('upload', 'route.ts'), readTemplate('api/upload-route.ts'))\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport fse from 'fs-extra'\n\n/**\n * Ensure a directory exists, creating it recursively if needed.\n */\nexport function ensureDir(dirPath: string): void {\n fse.ensureDirSync(dirPath)\n}\n\n/**\n * Write a file, creating parent directories as needed.\n * Will NOT overwrite an existing file unless `force` is true.\n * Returns true if the file was written, false if skipped.\n */\nexport function safeWriteFile(filePath: string, content: string, force = false): boolean {\n if (!force && fs.existsSync(filePath)) {\n return false\n }\n ensureDir(path.dirname(filePath))\n fs.writeFileSync(filePath, content, 'utf-8')\n return true\n}\n\n/**\n * Copy a single file, creating parent directories as needed.\n * Will NOT overwrite an existing file unless `force` is true.\n */\nexport function safeCopyFile(src: string, dest: string, force = false): boolean {\n if (!force && fs.existsSync(dest)) {\n return false\n }\n ensureDir(path.dirname(dest))\n fs.copyFileSync(src, dest)\n return true\n}\n\n/**\n * Recursively copy a directory of templates.\n * Skips existing files unless `force` is true.\n * Returns lists of written and skipped file paths.\n */\nexport function copyTemplateDir(\n srcDir: string,\n destDir: string,\n force = false\n): { written: string[]; skipped: string[] } {\n const written: string[] = []\n const skipped: string[] = []\n\n function walk(currentSrc: string, currentDest: string): void {\n const entries = fs.readdirSync(currentSrc, { withFileTypes: true })\n for (const entry of entries) {\n const srcPath = path.join(currentSrc, entry.name)\n const destPath = path.join(currentDest, entry.name)\n\n if (entry.isDirectory()) {\n walk(srcPath, destPath)\n } else {\n if (safeCopyFile(srcPath, destPath, force)) {\n written.push(destPath)\n } else {\n skipped.push(destPath)\n }\n }\n }\n }\n\n walk(srcDir, destDir)\n return { written, skipped }\n}\n\n/**\n * Append content to a file if the marker text is not already present.\n * Creates the file if it doesn't exist.\n * Returns true if content was appended.\n */\nexport function appendToFile(filePath: string, content: string, marker: string): boolean {\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, 'utf-8')\n if (existing.includes(marker)) {\n return false\n }\n fs.writeFileSync(filePath, `${existing.trimEnd()}\\n${content}\\n`, 'utf-8')\n } else {\n ensureDir(path.dirname(filePath))\n fs.writeFileSync(filePath, `${content}\\n`, 'utf-8')\n }\n return true\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface AuthScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create Better Auth config, client, and middleware in cms/lib/auth/.\n */\nexport function scaffoldAuth({ cwd, config }: AuthScaffoldOptions): string[] {\n const created: string[] = []\n const authDir = path.resolve(cwd, config.paths.cms, 'lib', 'auth')\n\n function write(filename: string, content: string): void {\n const fullPath = path.join(authDir, filename)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, 'lib', 'auth', filename))\n }\n }\n\n write('auth.ts', readTemplate('lib/auth/auth.ts'))\n write('auth-client.ts', readTemplate('lib/auth/auth-client.ts'))\n write('middleware.ts', readTemplate('lib/auth/middleware.ts'))\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\n\nexport interface BaseScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\nexport interface CmsDocOptions {\n preset?: string\n schemas?: string[]\n forms?: string[]\n}\n\n/**\n * Create the cms/ directory structure, cms.config.ts, and CMS.md.\n */\nexport function scaffoldBase({ cwd, config }: BaseScaffoldOptions): string[] {\n const created: string[] = []\n\n // Create cms/ subdirectories\n const cmsDirs = [\n config.paths.cms,\n config.paths.schemas,\n path.join(config.paths.cms, 'db'),\n path.join(config.paths.cms, 'db', 'migrations'),\n path.join(config.paths.cms, 'lib', 'auth'),\n path.join(config.paths.cms, 'lib', 'actions'),\n path.join(config.paths.cms, 'lib', 'cache'),\n path.join(config.paths.cms, 'lib', 'markdown'),\n path.join(config.paths.cms, 'lib', 'emails'),\n path.join(config.paths.cms, 'lib'),\n path.join(config.paths.cms, 'hooks'),\n path.join(config.paths.cms, 'components', 'ui'),\n path.join(config.paths.cms, 'components', 'form'),\n path.join(config.paths.cms, 'components', 'data-table'),\n path.join(config.paths.cms, 'components', 'layout'),\n path.join(config.paths.cms, 'components', 'shared'),\n path.join(config.paths.cms, 'types'),\n path.join(config.paths.cms, 'utils'),\n path.join(config.paths.cms, 'data')\n ]\n\n for (const dir of cmsDirs) {\n ensureDir(path.resolve(cwd, dir))\n }\n\n // Create app route directories\n const cmsDir = path.dirname(config.paths.pages)\n const appDirs = [\n config.paths.pages,\n config.paths.login,\n config.paths.api,\n path.join(cmsDir, '(account)', 'profile'),\n ]\n\n for (const dir of appDirs) {\n ensureDir(path.resolve(cwd, dir))\n }\n\n // Write cms.config.ts\n const configContent = generateConfigFile(config)\n if (safeWriteFile(path.resolve(cwd, 'cms.config.ts'), configContent)) {\n created.push('cms.config.ts')\n }\n\n // Write CMS.md (basic version — regenerated after preset with full info)\n const cmsDoc = generateCmsDoc(config, {})\n if (safeWriteFile(path.resolve(cwd, 'CMS.md'), cmsDoc)) {\n created.push('CMS.md')\n }\n\n return created\n}\n\n/**\n * Regenerate CMS.md with full documentation including preset and schema info.\n * Called after the preset step so generated schemas can be listed.\n */\nexport function regenerateCmsDoc(\n cwd: string,\n config: BetterstartConfig,\n options: CmsDocOptions\n): void {\n const content = generateCmsDoc(config, options)\n fs.writeFileSync(path.resolve(cwd, 'CMS.md'), content, 'utf-8')\n}\n\nfunction generateConfigFile(config: BetterstartConfig): string {\n return `import { defineConfig } from '@betterstart/cli'\n\nexport default defineConfig({\n srcDir: ${String(config.srcDir)},\n\n paths: {\n cms: '${config.paths.cms}',\n schemas: '${config.paths.schemas}',\n pages: '${config.paths.pages}',\n login: '${config.paths.login}',\n api: '${config.paths.api}',\n },\n\n database: {\n provider: '${config.database.provider}',\n migrationsDir: '${config.database.migrationsDir}',\n },\n\n features: {\n email: ${String(config.features.email)},\n },\n\n linter: '${config.linter}',\n\n generated: {\n entities: [],\n singles: [],\n forms: [],\n },\n})\n`\n}\n\nfunction generateCmsDoc(config: BetterstartConfig, options: CmsDocOptions): string {\n const sections: string[] = []\n\n // Header\n sections.push(`# CMS\n\n> Auto-generated by [BetterStart CLI](https://github.com/betterstart/cli).\n> Regenerated on each \\`betterstart init\\`.`)\n\n // Preset\n if (options.preset) {\n sections.push(`## Preset\n\nThis project was initialized with the **${options.preset}** preset.`)\n }\n\n // Directory structure\n sections.push(`## Directory Structure\n\n| Path | Description |\n|------|-------------|\n| \\`cms/\\` | All CMS source code (you own this) |\n| \\`cms/schemas/\\` | Entity JSON schemas |\n| \\`cms/schemas/forms/\\` | Form JSON schemas |\n| \\`cms/db/\\` | Database client, schema, drizzle config |\n| \\`cms/lib/actions/\\` | Server actions (CRUD) |\n| \\`cms/lib/auth/\\` | Better Auth configuration |\n| \\`cms/lib/cache/\\` | Cache tags, queries, revalidation |\n| \\`cms/lib/emails/\\` | React Email templates |\n| \\`cms/hooks/\\` | React Query hooks |\n| \\`cms/components/\\` | UI components (shadcn-style) |\n| \\`cms/utils/\\` | Utility functions |\n| \\`${config.paths.pages}/\\` | Admin pages (auth-gated) |\n| \\`${config.paths.login}/\\` | Login page |\n| \\`${config.paths.api}/\\` | CMS API routes |`)\n\n // Generated content\n if (\n (options.schemas && options.schemas.length > 0) ||\n (options.forms && options.forms.length > 0)\n ) {\n const lines: string[] = ['## Generated Content', '']\n if (options.schemas && options.schemas.length > 0) {\n lines.push('### Entities')\n for (const s of options.schemas) {\n lines.push(`- **${s}** — \\`cms/schemas/${s}.json\\` → admin at \\`/cms/${s}\\``)\n }\n }\n if (options.forms && options.forms.length > 0) {\n lines.push('')\n lines.push('### Forms')\n for (const f of options.forms) {\n lines.push(`- **${f}** — \\`cms/schemas/forms/${f}.json\\` → admin at \\`/cms/forms/${f}\\``)\n }\n }\n sections.push(lines.join('\\n'))\n }\n\n // Commands\n sections.push(`## Commands\n\n\\`\\`\\`bash\n# Generate entity CRUD from a schema\nnpx betterstart generate <schema-name>\n\n# Generate with force overwrite\nnpx betterstart generate <schema-name> --force\n\n# Remove all generated files for an entity/form\nnpx betterstart remove <schema-name>\n\n# Create initial admin user\nnpx betterstart seed\n\\`\\`\\``)\n\n // Schema format\n sections.push(`## Schema Format\n\n### Entity Schema (\\`cms/schemas/<name>.json\\`)\n\n\\`\\`\\`json\n{\n \"name\": \"posts\",\n \"label\": \"Posts\",\n \"icon\": \"FileText\",\n \"fields\": [\n { \"name\": \"title\", \"type\": \"string\", \"label\": \"Title\", \"required\": true },\n { \"name\": \"content\", \"type\": \"richtext\", \"label\": \"Content\" }\n ]\n}\n\\`\\`\\`\n\nField types: \\`string\\`, \\`text\\`, \\`richtext\\`, \\`number\\`, \\`boolean\\`, \\`date\\`, \\`image\\`, \\`select\\`, \\`relationship\\`.\n\n### Form Schema (\\`cms/schemas/forms/<name>.json\\`)\n\n\\`\\`\\`json\n{\n \"name\": \"contact\",\n \"label\": \"Contact Form\",\n \"submitButtonText\": \"Send Message\",\n \"fields\": [\n { \"name\": \"email\", \"type\": \"email\", \"label\": \"Email\", \"required\": true },\n { \"name\": \"message\", \"type\": \"textarea\", \"label\": \"Message\", \"required\": true }\n ]\n}\n\\`\\`\\`\n\nField types: \\`text\\`, \\`textarea\\`, \\`email\\`, \\`phone\\`, \\`number\\`, \\`url\\`, \\`date\\`, \\`select\\`, \\`radio\\`, \\`checkbox\\`, \\`multiselect\\`, \\`file\\`.`)\n\n // Path aliases\n sections.push(`## Path Aliases\n\n| Alias | Resolves to |\n|-------|-------------|\n| \\`@cms/*\\` | \\`${config.paths.cms}/*\\` |`)\n\n // Environment variables\n sections.push(`## Environment Variables\n\nRequired variables in \\`.env.local\\`:\n\n| Variable | Description |\n|----------|-------------|\n| \\`BETTERSTART_DATABASE_URL\\` | PostgreSQL connection string |\n| \\`BETTERSTART_AUTH_SECRET\\` | Auth secret (\\`openssl rand -base64 32\\`) |\n| \\`BETTERSTART_AUTH_URL\\` | App URL (e.g. \\`http://localhost:3000\\`) |\n| \\`BETTERSTART_R2_*\\` | Cloudflare R2 storage credentials |\n| \\`BETTERSTART_RESEND_API_KEY\\` | Resend API key (if email enabled) |\n| \\`NOTIFICATION_EMAIL\\` | Fallback notification email address |`)\n\n // Configuration\n sections.push(`## Configuration\n\nEdit \\`cms.config.ts\\` to customize paths, database provider, and features.`)\n\n return `${sections.join('\\n\\n')}\\n`\n}\n","/**\n * Biome scaffolder: creates biome.json if no existing linter is detected\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { LinterInfo } from '../../utils/detect.js'\n\nexport interface BiomeScaffoldResult {\n /** Whether Biome was set up */\n installed: boolean\n /** Reason it was skipped (if any) */\n skippedReason: string | null\n}\n\n/**\n * Create biome.json config if no linter exists.\n * Does NOT install the package — the dependency installer (task 5.05) handles that.\n */\nexport function scaffoldBiome(cwd: string, linter: LinterInfo): BiomeScaffoldResult {\n if (linter.type !== 'none') {\n return {\n installed: false,\n skippedReason: `${linter.type} already configured (${linter.configFile})`\n }\n }\n\n const configPath = path.join(cwd, 'biome.json')\n if (fs.existsSync(configPath)) {\n return { installed: false, skippedReason: 'biome.json already exists' }\n }\n\n const config = {\n $schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n vcs: {\n enabled: true,\n clientKind: 'git',\n useIgnoreFile: true\n },\n organizeImports: {\n enabled: true\n },\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 100\n },\n linter: {\n enabled: true,\n rules: {\n recommended: true,\n correctness: {\n noUnusedImports: 'warn',\n noUnusedVariables: 'warn'\n },\n style: {\n noNonNullAssertion: 'off'\n }\n }\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n semicolons: 'asNeeded'\n }\n },\n files: {\n ignore: [\n 'node_modules',\n '.next',\n 'dist',\n 'build',\n '*.config.js',\n '*.config.mjs',\n '*.config.cjs'\n ]\n }\n }\n\n fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, 'utf-8')\n return { installed: true, skippedReason: null }\n}\n","import path from 'node:path'\nimport fs from 'fs-extra'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { findCliRoot } from '../../utils/cli-root.js'\nimport { detectProjectName } from '../../utils/detect.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { cmsDataTemplate } from '../templates/data/cms.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface ComponentScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Copy all CMS components, hooks, types, utils, data, and lib code into the project.\n */\nexport function scaffoldComponents({ cwd, config }: ComponentScaffoldOptions): string[] {\n const cms = path.resolve(cwd, config.paths.cms)\n const created: string[] = []\n\n function write(relPath: string, content: string): void {\n const fullPath = path.join(cms, relPath)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, relPath))\n }\n }\n\n // --- CSS ---\n write('cms-globals.css', readTemplate('cms-globals.css'))\n\n // --- Components: layout ---\n write('components/layout/cms-providers.tsx', readTemplate('components/layout/cms-providers.tsx'))\n write('components/layout/cms-nav-link.tsx', readTemplate('components/layout/cms-nav-link.tsx'))\n write('components/layout/cms-sidebar.tsx', readTemplate('components/layout/cms-sidebar.tsx'))\n write('components/layout/cms-header.tsx', readTemplate('components/layout/cms-header.tsx'))\n write('components/layout/cms-search.tsx', readTemplate('components/layout/cms-search.tsx'))\n // --- Components: shared ---\n write('components/shared/page-header.tsx', readTemplate('components/shared/page-header.tsx'))\n write('components/shared/delete-dialog.tsx', readTemplate('components/shared/delete-dialog.tsx'))\n write('components/shared/status-badge.tsx', readTemplate('components/shared/status-badge.tsx'))\n\n // --- Components: data-table ---\n write('components/data-table/data-table.tsx', readTemplate('components/data-table/data-table.tsx'))\n write('components/data-table/data-table-pagination.tsx', readTemplate('components/data-table/data-table-pagination.tsx'))\n write('components/data-table/data-table-toolbar.tsx', readTemplate('components/data-table/data-table-toolbar.tsx'))\n\n // --- Components: ui (raw file copy) ---\n const uiCreated = copyUiTemplates(cwd, config)\n created.push(...uiCreated)\n\n // --- Components: ui/tiptap (recursive copy) ---\n const tiptapCreated = copyTiptapTemplates(cwd, config)\n created.push(...tiptapCreated)\n\n // --- Types ---\n write('types/index.ts', readTemplate('types/index.ts'))\n write('types/auth.ts', readTemplate('types/auth.ts'))\n write('types/table-meta.ts', readTemplate('types/table-meta.ts'))\n\n // --- Utils ---\n write('utils/cn.ts', readTemplate('utils/cn.ts'))\n write('utils/seo.ts', readTemplate('utils/seo.ts'))\n write('utils/validation.ts', readTemplate('utils/validation.ts'))\n write('utils/webhook.ts', readTemplate('utils/webhook.ts'))\n write('utils/mailchimp.ts', readTemplate('utils/mailchimp.ts'))\n\n // --- Hooks ---\n write('hooks/use-upload.ts', readTemplate('hooks/use-upload.ts'))\n write('hooks/use-editor-image-upload.ts', readTemplate('hooks/use-editor-image-upload.ts'))\n write('hooks/use-local-storage.ts', readTemplate('hooks/use-local-storage.ts'))\n write('hooks/use-cms-theme.tsx', readTemplate('hooks/use-cms-theme.tsx'))\n write('hooks/use-users.ts', readTemplate('hooks/use-users.ts'))\n write('hooks/use-mobile.ts', readTemplate('hooks/use-mobile.ts'))\n\n // --- Data ---\n const projectName = detectProjectName(cwd)\n write('data/cms.ts', cmsDataTemplate(projectName))\n write('data/navigation.ts', readTemplate('data/navigation.ts'))\n\n // --- Lib ---\n write('lib/r2.ts', readTemplate('lib/r2.ts'))\n write('lib/actions/form-settings.ts', readTemplate('lib/actions/form-settings.ts'))\n write('lib/actions/upload.ts', readTemplate('lib/actions/upload.ts'))\n write('lib/actions/users.ts', readTemplate('lib/actions/users.ts'))\n\n // --- Markdown ---\n write('lib/markdown/render.ts', readTemplate('lib/markdown/render.ts'))\n write('lib/markdown/format.ts', readTemplate('lib/markdown/format.ts'))\n write('lib/markdown/cached.ts', readTemplate('lib/markdown/cached.ts'))\n\n // --- Schema metaschema ---\n const schemaCreated = copySchemaMetaschema(cwd, config)\n created.push(...schemaCreated)\n\n return created\n}\n\n/**\n * Copy raw .tsx UI component files from the CLI's templates/ui/ directory.\n */\nfunction copyUiTemplates(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const destDir = path.resolve(cwd, config.paths.cms, 'components', 'ui')\n\n const cliRoot = findCliRoot()\n const srcDir = path.join(cliRoot, 'templates', 'ui')\n\n if (!fs.existsSync(srcDir)) {\n return created\n }\n\n const files = fs\n .readdirSync(srcDir)\n .filter((f: string) => f.endsWith('.tsx') || f.endsWith('.ts'))\n\n for (const file of files) {\n const destPath = path.join(destDir, file)\n if (!fs.existsSync(destPath)) {\n fs.copyFileSync(path.join(srcDir, file), destPath)\n created.push(path.join(config.paths.cms, 'components', 'ui', file))\n }\n }\n\n return created\n}\n\n/**\n * Recursively copy the TipTap editor directory from templates/tiptap/ → cms/components/ui/tiptap/.\n */\nfunction copyTiptapTemplates(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const cliRoot = findCliRoot()\n const srcDir = path.join(cliRoot, 'templates', 'tiptap')\n const destDir = path.resolve(cwd, config.paths.cms, 'components', 'ui', 'tiptap')\n\n if (!fs.existsSync(srcDir)) {\n return created\n }\n\n copyDirRecursive(srcDir, destDir, config.paths.cms, created)\n return created\n}\n\nfunction copyDirRecursive(src: string, dest: string, cmsPrefix: string, created: string[]): void {\n fs.ensureDirSync(dest)\n const entries = fs.readdirSync(src, { withFileTypes: true })\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n if (entry.isDirectory()) {\n copyDirRecursive(srcPath, destPath, cmsPrefix, created)\n } else if (!fs.existsSync(destPath)) {\n fs.copyFileSync(srcPath, destPath)\n const relFromCms = path.relative(path.resolve(dest, '..', '..', '..', '..'), destPath)\n created.push(relFromCms)\n }\n }\n}\n\n/**\n * Copy schema.json metaschema into cms/schemas/ so users get IDE validation.\n */\nfunction copySchemaMetaschema(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const cliRoot = findCliRoot()\n const srcPath = path.join(cliRoot, 'templates', 'schema.json')\n const destPath = path.resolve(cwd, config.paths.schemas, 'schema.json')\n\n if (fs.existsSync(srcPath) && !fs.existsSync(destPath)) {\n fs.ensureDirSync(path.dirname(destPath))\n fs.copyFileSync(srcPath, destPath)\n created.push(path.join(config.paths.schemas, 'schema.json'))\n }\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type LinterType = 'eslint' | 'biome' | 'none'\n\nexport interface LinterInfo {\n /** Detected linter type */\n type: LinterType\n /** Config file found (if any) */\n configFile: string | null\n}\n\nexport interface ProjectInfo {\n /** Whether this is an existing Next.js project */\n isExisting: boolean\n /** Whether the project uses a src/ directory */\n hasSrcDir: boolean\n /** Whether TypeScript is configured */\n hasTypeScript: boolean\n /** Whether Tailwind CSS is configured */\n hasTailwind: boolean\n /** Detected linter info */\n linter: LinterInfo\n /** Conflicts found that would block init */\n conflicts: string[]\n}\n\nconst NEXT_CONFIG_FILES = ['next.config.ts', 'next.config.js', 'next.config.mjs']\n\nexport function detectProjectName(cwd: string): string {\n const pkgPath = path.join(cwd, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n if (typeof pkg.name === 'string' && pkg.name.length > 0) {\n return formatProjectName(pkg.name)\n }\n } catch {\n /* ignore */\n }\n }\n return formatProjectName(path.basename(cwd))\n}\n\nfunction formatProjectName(name: string): string {\n const base = name.includes('/') ? name.split('/').pop()! : name\n return base\n .replace(/[-_]+/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n .trim()\n}\n\nexport function detectProject(cwd: string): ProjectInfo {\n const isExisting = NEXT_CONFIG_FILES.some((f) => fs.existsSync(path.join(cwd, f)))\n\n const hasSrcDir = fs.existsSync(path.join(cwd, 'src'))\n\n const hasTypeScript =\n fs.existsSync(path.join(cwd, 'tsconfig.json')) ||\n fs.existsSync(path.join(cwd, 'tsconfig.app.json'))\n\n const hasTailwind = detectTailwind(cwd)\n const linter = detectLinter(cwd)\n\n const conflicts: string[] = []\n if (isExisting) {\n if (fs.existsSync(path.join(cwd, 'cms'))) {\n conflicts.push('cms/ directory already exists')\n }\n if (fs.existsSync(path.join(cwd, 'cms.config.ts'))) {\n conflicts.push('cms.config.ts already exists')\n }\n\n const appBase = hasSrcDir ? 'src/app' : 'app'\n if (fs.existsSync(path.join(cwd, appBase, '(cms)'))) {\n conflicts.push(`${appBase}/(cms)/ route group already exists`)\n }\n\n if (hasTsconfigCmsAliases(cwd)) {\n conflicts.push('@cms/* path aliases already exist in tsconfig.json')\n }\n\n if (hasEnvBetterstartVars(cwd)) {\n conflicts.push('BETTERSTART_* variables already exist in .env.local')\n }\n }\n\n return { isExisting, hasSrcDir, hasTypeScript, hasTailwind, linter, conflicts }\n}\n\n// ============================================================================\n// Linter Detection\n// ============================================================================\n\nconst BIOME_CONFIG_FILES = ['biome.json', 'biome.jsonc']\n\nconst ESLINT_CONFIG_FILES = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n '.eslintrc.json',\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n '.eslintrc'\n]\n\nexport function detectLinter(cwd: string): LinterInfo {\n // Check for Biome first (preferred)\n for (const f of BIOME_CONFIG_FILES) {\n if (fs.existsSync(path.join(cwd, f))) {\n return { type: 'biome', configFile: f }\n }\n }\n\n // Check for ESLint config files\n for (const f of ESLINT_CONFIG_FILES) {\n if (fs.existsSync(path.join(cwd, f))) {\n return { type: 'eslint', configFile: f }\n }\n }\n\n // Check package.json for eslintConfig field\n const pkgPath = path.join(cwd, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n if (pkg.eslintConfig) {\n return { type: 'eslint', configFile: 'package.json (eslintConfig)' }\n }\n } catch {\n // ignore parse errors\n }\n }\n\n return { type: 'none', configFile: null }\n}\n\n// ============================================================================\n// Tailwind Detection\n// ============================================================================\n\nfunction detectTailwind(cwd: string): boolean {\n // Tailwind v4: check for CSS files with @import \"tailwindcss\" or @theme\n const cssFiles = ['globals.css', 'app.css', 'index.css'].flatMap((f) => [\n path.join(cwd, 'src', 'app', f),\n path.join(cwd, 'app', f),\n path.join(cwd, 'src', f),\n path.join(cwd, f)\n ])\n\n for (const cssFile of cssFiles) {\n if (fs.existsSync(cssFile)) {\n const content = fs.readFileSync(cssFile, 'utf-8')\n if (\n content.includes('@import \"tailwindcss\"') ||\n content.includes(\"@import 'tailwindcss'\") ||\n content.includes('@theme')\n ) {\n return true\n }\n }\n }\n\n // Also check postcss.config for tailwindcss plugin (v3 style)\n const postcssFiles = ['postcss.config.js', 'postcss.config.mjs', 'postcss.config.cjs']\n for (const f of postcssFiles) {\n if (fs.existsSync(path.join(cwd, f))) {\n const content = fs.readFileSync(path.join(cwd, f), 'utf-8')\n if (content.includes('tailwindcss') || content.includes('@tailwindcss')) {\n return true\n }\n }\n }\n\n return false\n}\n\nfunction hasTsconfigCmsAliases(cwd: string): boolean {\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n if (!fs.existsSync(tsconfigPath)) return false\n\n try {\n const content = fs.readFileSync(tsconfigPath, 'utf-8')\n return content.includes('@cms/')\n } catch {\n return false\n }\n}\n\nfunction hasEnvBetterstartVars(cwd: string): boolean {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return false\n\n try {\n const content = fs.readFileSync(envPath, 'utf-8')\n return content.includes('BETTERSTART_')\n } catch {\n return false\n }\n}\n","/**\n * Template: cms/data/cms.ts\n * CMS metadata (project name, etc.)\n */\nexport function cmsDataTemplate(projectName: string): string {\n return `export const cms = {\n name: '${projectName}',\n}\n`\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface DatabaseScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create database client, schema, and drizzle config in cms/db/.\n */\nexport function scaffoldDatabase({ cwd, config }: DatabaseScaffoldOptions): string[] {\n const created: string[] = []\n const dbDir = path.resolve(cwd, config.paths.cms, 'db')\n\n function write(filename: string, content: string): void {\n const fullPath = path.join(dbDir, filename)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, 'db', filename))\n }\n }\n\n write('client.ts', readTemplate('db/client.ts'))\n write('schema.ts', readTemplate('db/schema.ts'))\n\n // Drizzle config goes at project root (where drizzle-kit expects it)\n const drizzleConfigPath = path.resolve(cwd, 'drizzle.config.ts')\n if (safeWriteFile(drizzleConfigPath, readTemplate('drizzle.config.ts'))) {\n created.push('drizzle.config.ts')\n }\n\n return created\n}\n","/**\n * Dependency installer: auto-install all required deps via detected package manager.\n * Splits into core (production) and dev dependencies.\n * Optionally includes email deps (resend + @react-email/components).\n * Uses async spawn so the clack spinner can animate during install.\n */\n\nimport { spawn } from 'node:child_process'\nimport type { PackageManager } from '../../utils/package-manager.js'\n\nexport interface InstallDepsOptions {\n cwd: string\n pm: PackageManager\n includeEmail: boolean\n includeBiome: boolean\n}\n\nexport interface InstallDepsResult {\n coreDeps: string[]\n devDeps: string[]\n success: boolean\n error: string | null\n}\n\n// ============================================================================\n// Dependency Lists\n// ============================================================================\n\n/** Core runtime deps — always installed */\nexport const CORE_DEPS = [\n // Database\n 'drizzle-orm',\n '@neondatabase/serverless',\n // Auth\n 'better-auth',\n // Data fetching + tables\n '@tanstack/react-query',\n '@tanstack/react-table',\n '@tanstack/react-virtual',\n // Forms + validation\n 'react-hook-form',\n '@hookform/resolvers',\n 'zod',\n // URL state + toast + theme\n 'nuqs',\n 'sonner',\n // Styling utilities\n 'geist',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n // Icons\n 'lucide-react',\n // Storage (R2)\n '@aws-sdk/client-s3',\n // Radix UI (unified package + legacy scoped packages)\n 'radix-ui',\n '@radix-ui/react-accordion',\n '@radix-ui/react-alert-dialog',\n '@radix-ui/react-aspect-ratio',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-collapsible',\n '@radix-ui/react-context-menu',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-hover-card',\n '@radix-ui/react-label',\n '@radix-ui/react-menubar',\n '@radix-ui/react-navigation-menu',\n '@radix-ui/react-popover',\n '@radix-ui/react-progress',\n '@radix-ui/react-radio-group',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-separator',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-switch',\n '@radix-ui/react-tabs',\n '@radix-ui/react-toast',\n '@radix-ui/react-toggle',\n '@radix-ui/react-toggle-group',\n '@radix-ui/react-tooltip',\n // Rich text (TipTap)\n '@tiptap/core',\n '@tiptap/pm',\n '@tiptap/react',\n '@tiptap/starter-kit',\n '@tiptap/extension-highlight',\n '@tiptap/extension-horizontal-rule',\n '@tiptap/extension-image',\n '@tiptap/extension-list',\n '@tiptap/extension-placeholder',\n '@tiptap/extension-subscript',\n '@tiptap/extension-superscript',\n '@tiptap/extension-text-align',\n '@tiptap/extension-typography',\n '@tiptap/extensions',\n 'tiptap-markdown',\n '@floating-ui/react',\n 'react-hotkeys-hook',\n 'lodash.throttle',\n // CodeMirror markdown editor\n '@codemirror/lang-markdown',\n '@codemirror/view',\n '@uiw/codemirror-theme-github',\n '@uiw/react-codemirror',\n // Date\n 'date-fns',\n 'react-day-picker',\n // Markdown rendering\n 'shiki',\n '@shikijs/transformers',\n 'katex',\n 'markdown-it',\n // Drag-and-drop\n '@dnd-kit/core',\n '@dnd-kit/sortable',\n '@dnd-kit/utilities',\n // Other UI\n 'cmdk',\n 'embla-carousel-react',\n 'fuse.js',\n 'input-otp',\n 'react-resizable-panels',\n 'recharts',\n 'shadcn',\n 'tw-animate-css',\n 'usehooks-ts',\n 'vaul'\n]\n\n/** Email deps — only when email feature is enabled */\nexport const EMAIL_DEPS = ['resend', '@react-email/components']\n\n/** Mailchimp deps — always installed (fire-and-forget, no-op without env vars) */\nexport const MAILCHIMP_DEPS = ['@mailchimp/mailchimp_marketing']\n\n/** Mailchimp type definitions */\nexport const MAILCHIMP_DEV_DEPS = ['@types/mailchimp__mailchimp_marketing']\n\n/** Dev deps — always installed */\nexport const DEV_DEPS = ['drizzle-kit', 'tsx', 'sass', '@types/katex', '@types/markdown-it@13']\n\n/** Biome dev dep — only when no existing linter */\nexport const BIOME_DEV_DEPS = ['@biomejs/biome']\n\n// ============================================================================\n// Installer\n// ============================================================================\n\nfunction buildAddArgs(pm: PackageManager, deps: string[], dev: boolean): string[] {\n const devFlag = dev ? (pm === 'yarn' ? '--dev' : '-D') : ''\n\n switch (pm) {\n case 'pnpm':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n case 'yarn':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n case 'bun':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n default:\n return ['install', ...(devFlag ? [devFlag] : []), ...deps]\n }\n}\n\nfunction spawnAsync(cmd: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { cwd, stdio: 'pipe' })\n let stderr = ''\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(stderr || `${cmd} exited with code ${code}`))\n })\n child.on('error', reject)\n })\n}\n\nexport async function installDependenciesAsync({\n cwd,\n pm,\n includeEmail,\n includeBiome\n}: InstallDepsOptions): Promise<InstallDepsResult> {\n const coreDeps = [...CORE_DEPS, ...MAILCHIMP_DEPS]\n if (includeEmail) coreDeps.push(...EMAIL_DEPS)\n\n const devDeps = [...DEV_DEPS, ...MAILCHIMP_DEV_DEPS]\n if (includeBiome) devDeps.push(...BIOME_DEV_DEPS)\n\n try {\n // Install core deps\n await spawnAsync(pm, buildAddArgs(pm, coreDeps, false), cwd)\n\n // Install dev deps\n await spawnAsync(pm, buildAddArgs(pm, devDeps, true), cwd)\n\n return { coreDeps, devDeps, success: true, error: null }\n } catch (err) {\n return {\n coreDeps,\n devDeps,\n success: false,\n error: err instanceof Error ? err.message : 'Install failed'\n }\n }\n}\n","import crypto from 'node:crypto'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { EnvSection } from '../../utils/env.js'\nimport { appendEnvVars } from '../../utils/env.js'\n\nexport function detectDevPort(cwd: string): number {\n const pkgPath = join(cwd, 'package.json')\n if (!existsSync(pkgPath)) return 3000\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n scripts?: Record<string, string>\n }\n const devScript = pkg.scripts?.dev ?? ''\n const match = devScript.match(/--port\\s+(\\d+)|-p\\s+(\\d+)/)\n if (match) {\n const port = Number.parseInt(match[1] ?? match[2], 10)\n if (port > 0 && port <= 65535) return port\n }\n } catch {\n // ignore parse errors\n }\n return 3000\n}\n\nfunction getCoreEnvSections(\n databaseUrl: string | undefined,\n devPort: number\n): EnvSection[] {\n const authSecret = crypto.randomBytes(32).toString('base64')\n return [\n {\n header: 'Database (Neon)',\n vars: [{ key: 'BETTERSTART_DATABASE_URL', value: databaseUrl ?? 'postgresql://...' }]\n },\n {\n header: 'Authentication',\n vars: [\n { key: 'BETTERSTART_AUTH_SECRET', value: authSecret },\n { key: 'BETTERSTART_AUTH_URL', value: `http://localhost:${devPort}` },\n { key: 'BETTERSTART_AUTH_BASE_PATH', value: '/api/cms/auth' }\n ]\n },\n {\n header: 'Storage (Cloudflare R2)',\n vars: [\n { key: 'BETTERSTART_R2_ACCOUNT_ID', value: '' },\n { key: 'BETTERSTART_R2_ACCESS_KEY_ID', value: '' },\n { key: 'BETTERSTART_R2_SECRET_ACCESS_KEY', value: '' },\n { key: 'BETTERSTART_R2_BUCKET_NAME', value: '' },\n { key: 'BETTERSTART_R2_PUBLIC_URL', value: '' }\n ]\n }\n ]\n}\n\nfunction getEmailEnvSection(): EnvSection {\n return {\n header: 'Email (Resend)',\n vars: [\n { key: 'BETTERSTART_RESEND_API_KEY', value: '' },\n { key: 'BETTERSTART_EMAIL_FROM', value: 'noreply@yourdomain.com' }\n ]\n }\n}\n\nfunction getMailchimpEnvSection(): EnvSection {\n return {\n header: 'Mailchimp (optional — leave blank to disable)',\n vars: [\n { key: 'BETTERSTART_MAILCHIMP_API_KEY', value: '' },\n { key: 'BETTERSTART_MAILCHIMP_SERVER_PREFIX', value: '' },\n { key: 'BETTERSTART_MAILCHIMP_AUDIENCE_ID', value: '' }\n ]\n }\n}\n\n/**\n * Append BETTERSTART_* environment variables to .env.local.\n */\nexport function scaffoldEnv(\n cwd: string,\n options: { includeEmail: boolean; databaseUrl?: string }\n): { added: string[]; skipped: string[]; updated: string[] } {\n const devPort = detectDevPort(cwd)\n const sections = getCoreEnvSections(options.databaseUrl, devPort)\n if (options.includeEmail) {\n sections.push(getEmailEnvSection())\n }\n sections.push(getMailchimpEnvSection())\n // If the user provided a real database URL, overwrite any existing placeholder\n const overwrite = options.databaseUrl ? new Set(['BETTERSTART_DATABASE_URL']) : undefined\n return appendEnvVars(cwd, sections, overwrite)\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface EnvVar {\n key: string\n value: string\n comment?: string\n}\n\nexport interface EnvSection {\n header: string\n vars: EnvVar[]\n}\n\n/**\n * Safely append environment variables to .env.local.\n * Never overwrites existing values — only adds missing keys.\n * Keys listed in `overwrite` will be updated even if they already exist.\n */\nexport function appendEnvVars(\n cwd: string,\n sections: EnvSection[],\n overwrite?: Set<string>\n): { added: string[]; skipped: string[]; updated: string[] } {\n const envPath = path.join(cwd, '.env.local')\n let existing = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf-8') : ''\n\n const existingKeys = new Set(\n existing\n .split('\\n')\n .filter((line) => line.trim() && !line.trim().startsWith('#'))\n .map((line) => line.split('=')[0]?.trim())\n .filter(Boolean)\n )\n\n const added: string[] = []\n const skipped: string[] = []\n const updated: string[] = []\n const lines: string[] = []\n\n // In-place update for overwrite keys that already exist\n if (overwrite) {\n for (const section of sections) {\n for (const v of section.vars) {\n if (overwrite.has(v.key) && existingKeys.has(v.key)) {\n const pattern = new RegExp(`^${v.key}=.*$`, 'm')\n const replacement = v.comment\n ? `${v.key}=\"${v.value}\" # ${v.comment}`\n : `${v.key}=\"${v.value}\"`\n existing = existing.replace(pattern, replacement)\n updated.push(v.key)\n }\n }\n }\n }\n\n if (existing.trim()) {\n lines.push('')\n }\n\n for (const section of sections) {\n const sectionVars = section.vars.filter((v) => {\n if (existingKeys.has(v.key)) {\n if (!updated.includes(v.key)) skipped.push(v.key)\n return false\n }\n added.push(v.key)\n return true\n })\n\n if (sectionVars.length === 0) continue\n\n lines.push(`# ${section.header}`)\n for (const v of sectionVars) {\n const line = v.comment ? `${v.key}=\"${v.value}\" # ${v.comment}` : `${v.key}=\"${v.value}\"`\n lines.push(line)\n }\n lines.push('')\n }\n\n if (added.length > 0 || updated.length > 0) {\n const header = existing.trim()\n ? ''\n : '# ============================================\\n# BetterStart CMS\\n# ============================================\\n'\n const content = existing.trim()\n ? `${existing.trimEnd()}\\n${lines.join('\\n')}`\n : header + lines.join('\\n')\n fs.writeFileSync(envPath, content)\n }\n\n return { added, skipped, updated }\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface LayoutScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create all CMS route structures: layouts, login, dashboard, users, settings.\n */\nexport function scaffoldLayout({ cwd, config }: LayoutScaffoldOptions): string[] {\n const created: string[] = []\n\n function write(relPath: string, content: string): void {\n const fullPath = path.resolve(cwd, relPath)\n ensureDir(path.dirname(fullPath))\n if (safeWriteFile(fullPath, content)) {\n created.push(relPath)\n }\n }\n\n // Derive base CMS layout dir from pages path\n // pages = \"./src/app/(cms)/cms/(authenticated)\" → cmsDir = \"./src/app/(cms)/cms\"\n const cmsDir = path.dirname(config.paths.pages)\n\n // --- Shared CMS layout ---\n write(path.join(cmsDir, 'layout.tsx'), readTemplate('pages/cms-layout.tsx'))\n\n // --- Authenticated layout ---\n write(path.join(config.paths.pages, 'layout.tsx'), readTemplate('pages/authenticated-layout.tsx'))\n\n // --- Login page ---\n write(path.join(config.paths.login, 'page.tsx'), readTemplate('pages/login-page.tsx'))\n write(path.join(config.paths.login, 'login-form.tsx'), readTemplate('pages/login-form.tsx'))\n\n // --- Dashboard ---\n write(path.join(config.paths.pages, 'page.tsx'), readTemplate('pages/dashboard-page.tsx'))\n\n // --- Users pages ---\n const usersDir = path.join(config.paths.pages, 'users')\n write(path.join(usersDir, 'page.tsx'), readTemplate('pages/users/users-page.tsx'))\n write(path.join(usersDir, 'users-page-content.tsx'), readTemplate('pages/users/users-page-content.tsx'))\n write(path.join(usersDir, 'users-table.tsx'), readTemplate('pages/users/users-table.tsx'))\n write(path.join(usersDir, 'columns.tsx'), readTemplate('pages/users/columns.tsx'))\n write(path.join(usersDir, 'create-user-dialog.tsx'), readTemplate('pages/users/create-user-dialog.tsx'))\n write(path.join(usersDir, 'edit-role-dialog.tsx'), readTemplate('pages/users/edit-role-dialog.tsx'))\n\n // --- Account layout + Profile page ---\n const accountDir = path.join(cmsDir, '(account)')\n write(path.join(accountDir, 'layout.tsx'), readTemplate('pages/account-layout.tsx'))\n\n const profileDir = path.join(accountDir, 'profile')\n write(path.join(profileDir, 'page.tsx'), readTemplate('pages/profile/profile-page.tsx'))\n write(path.join(profileDir, 'profile-form.tsx'), readTemplate('pages/profile/profile-form.tsx'))\n\n // --- Profile action + Sign-out component ---\n const cms = path.resolve(cwd, config.paths.cms)\n write(path.join(cms, 'lib', 'actions', 'profile.ts'), readTemplate('lib/actions/profile.ts'))\n write(path.join(cms, 'components', 'layout', 'cms-sign-out.tsx'), readTemplate('components/layout/cms-sign-out.tsx'))\n\n return created\n}\n","/**\n * Preset scaffolder: copy preset schemas into cms/schemas/ and run generate\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { runFormPipeline } from '../../generators/form-pipeline/index.js'\nimport { runEntityPipeline, runSinglePipeline } from '../../generators/index.js'\nimport type { FormSchema, Schema } from '../../types.js'\nimport type { Preset } from '../prompts/features.js'\nimport { blogCategoriesSchema } from '../templates/presets/blog-categories.js'\nimport { blogPostsSchema } from '../templates/presets/blog-posts.js'\nimport { defaultSettingsSchema } from '../templates/presets/default-settings.js'\nimport { fullContactSchema } from '../templates/presets/full-contact.js'\nimport { fullNavigationSchema } from '../templates/presets/full-navigation.js'\n\nexport interface PresetScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n preset: Preset\n}\n\nexport interface PresetScaffoldResult {\n schemas: string[]\n generatedFiles: string[]\n errors: string[]\n}\n\ninterface PresetSchema {\n filename: string\n content: string\n isForm: boolean\n isSingle: boolean\n}\n\nfunction getPresetSchemas(preset: Preset): PresetSchema[] {\n // Settings schema is always included (even for blank preset)\n const schemas: PresetSchema[] = [\n {\n filename: 'settings.json',\n content: defaultSettingsSchema(),\n isForm: false,\n isSingle: true\n }\n ]\n\n if (preset !== 'blank') {\n schemas.push(\n {\n filename: 'categories.json',\n content: blogCategoriesSchema(),\n isForm: false,\n isSingle: false\n },\n { filename: 'posts.json', content: blogPostsSchema(), isForm: false, isSingle: false }\n )\n }\n\n if (preset === 'full') {\n schemas.push(\n {\n filename: 'navigation.json',\n content: fullNavigationSchema(),\n isForm: false,\n isSingle: false\n },\n {\n filename: 'forms/contact.json',\n content: fullContactSchema(),\n isForm: true,\n isSingle: false\n }\n )\n }\n\n return schemas\n}\n\n/**\n * Apply preset: write schema files and run entity generation for each\n */\nexport function scaffoldPreset({\n cwd,\n config,\n preset\n}: PresetScaffoldOptions): PresetScaffoldResult {\n const result: PresetScaffoldResult = {\n schemas: [],\n generatedFiles: [],\n errors: []\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n const presetSchemas = getPresetSchemas(preset)\n\n // 1. Write all schema files first\n for (const ps of presetSchemas) {\n const filePath = path.join(schemasDir, ps.filename)\n const dir = path.dirname(filePath)\n\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n\n fs.writeFileSync(filePath, ps.content, 'utf-8')\n result.schemas.push(ps.filename)\n }\n\n // 2. Run pipelines for each schema\n for (const ps of presetSchemas) {\n try {\n if (ps.isForm) {\n const schema = JSON.parse(ps.content) as FormSchema\n const pipelineResult = runFormPipeline(schema, cwd, config, { force: true, silent: true })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n } else if (ps.isSingle) {\n const schema = JSON.parse(ps.content) as Schema\n const pipelineResult = runSinglePipeline(schema, cwd, config, {\n force: true,\n silent: true\n })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n } else {\n const schema = JSON.parse(ps.content) as Schema\n const pipelineResult = runEntityPipeline(schema, cwd, config, {\n force: true,\n silent: true\n })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n }\n } catch (err) {\n result.errors.push(`${ps.filename}: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n return result\n}\n","/**\n * Blog preset: categories.json schema\n * Simple entity with name, slug, description, color\n */\nexport function blogCategoriesSchema(): string {\n return JSON.stringify(\n {\n name: 'categories',\n label: 'Categories',\n description: 'Organize posts with categories',\n icon: 'Tag',\n navGroup: { label: 'Blog', icon: 'BookOpen' },\n fields: [\n {\n name: 'name',\n type: 'string',\n label: 'Name',\n required: true,\n hint: 'Category name'\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from name)',\n hidden: true\n },\n {\n name: 'description',\n type: 'text',\n label: 'Description',\n hint: 'Optional description of the category'\n },\n {\n name: 'color',\n type: 'string',\n label: 'Color',\n hint: 'Optional color code for UI display (e.g., #3B82F6)'\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'slug',\n header: 'Slug',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'description',\n header: 'Description',\n type: 'text',\n sortable: false\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true\n },\n search: {\n fields: ['name', 'description']\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'name',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","/**\n * Blog preset: posts.json schema\n * Entity with M2M relationship to categories, richtext content, auto-slugify\n */\nexport function blogPostsSchema(): string {\n return JSON.stringify(\n {\n name: 'posts',\n label: 'Posts',\n description: 'Manage blog posts and articles',\n icon: 'FileText',\n navGroup: { label: 'Blog', icon: 'BookOpen' },\n fields: [\n {\n name: 'title',\n type: 'string',\n label: 'Title',\n required: true\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from title)',\n hidden: true\n },\n {\n name: 'categories',\n type: 'relationship',\n relationship: 'categories',\n label: 'Categories',\n multiple: true,\n hint: 'Assign one or more categories'\n },\n {\n name: 'excerpt',\n type: 'text',\n label: 'Excerpt',\n hint: 'Short summary for listing pages'\n },\n {\n name: 'coverImage',\n type: 'image',\n label: 'Cover Image'\n },\n {\n name: 'content',\n type: 'richtext',\n label: 'Content',\n output: 'html'\n }\n ],\n columns: [\n {\n accessorKey: 'title',\n header: 'Title',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'published',\n header: 'Status',\n type: 'boolean',\n sortable: true\n },\n {\n accessorKey: 'updatedAt',\n header: 'Updated',\n type: 'date',\n sortable: true\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true,\n draft: true\n },\n search: {\n fields: ['title', 'excerpt']\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'title',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","/**\n * Default settings schema (applied to ALL presets including blank)\n * Generates a singleton form at /cms/settings\n */\nexport function defaultSettingsSchema(): string {\n return JSON.stringify(\n {\n name: 'settings',\n type: 'single',\n label: 'Settings',\n description: 'General Settings',\n icon: 'Settings',\n fields: [\n {\n type: 'section',\n name: 'siteSettings',\n label: 'Site Settings',\n description: 'General settings for the site',\n fields: [\n { name: 'appName', type: 'string', label: 'App Name', hint: 'Displayed in the sidebar and throughout the dashboard', default: 'BetterStart' },\n { name: 'appDescription', type: 'text', label: 'App Description', hint: 'A brief description of the application' }\n ]\n },\n {\n type: 'section',\n name: 'branding',\n label: 'Branding',\n description: 'Logo and visual identity',\n fields: [\n { name: 'logo', type: 'image', label: 'Logo' }\n ]\n }\n ]\n },\n null,\n 2\n )\n}\n","/**\n * Full preset: contact.json form schema\n * Public contact form with admin submission viewer\n */\nexport function fullContactSchema(): string {\n return JSON.stringify(\n {\n name: 'contact',\n label: 'Contact Form',\n description: 'Website contact form submissions',\n icon: 'Mail',\n submitButtonText: 'Send Message',\n successMessage: \"Thank you! We'll get back to you soon.\",\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Full Name',\n placeholder: 'Jane Doe',\n required: true,\n minLength: 2,\n maxLength: 100\n },\n {\n name: 'email',\n type: 'email',\n label: 'Email Address',\n placeholder: 'jane@example.com',\n required: true\n },\n {\n name: 'subject',\n type: 'select',\n label: 'Subject',\n required: true,\n options: [\n { label: 'General Inquiry', value: 'general' },\n { label: 'Support', value: 'support' },\n { label: 'Feedback', value: 'feedback' },\n { label: 'Other', value: 'other' }\n ]\n },\n {\n name: 'message',\n type: 'textarea',\n label: 'Message',\n placeholder: 'How can we help?',\n required: true,\n minLength: 10\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'email',\n header: 'Email',\n type: 'email',\n sortable: true\n },\n {\n accessorKey: 'subject',\n header: 'Subject',\n type: 'badge',\n sortable: true\n },\n {\n accessorKey: 'submittedAt',\n header: 'Submitted',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n export: true,\n delete: true\n }\n },\n null,\n 2\n )\n}\n","/**\n * Full preset: navigation.json schema\n * Entity for managing website navigation menus with nested items\n */\nexport function fullNavigationSchema(): string {\n return JSON.stringify(\n {\n name: 'navigation',\n label: 'Navigation',\n description: 'Manage website navigation menus',\n icon: 'Navigation',\n fields: [\n {\n name: 'name',\n type: 'string',\n label: 'Name',\n required: true,\n hint: 'Navigation name (e.g., Main, Footer)'\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from name)',\n hidden: true\n },\n {\n name: 'navItems',\n type: 'list',\n label: 'Navigation Items',\n fields: [\n {\n name: 'title',\n type: 'string',\n label: 'Title'\n },\n {\n name: 'url',\n type: 'string',\n label: 'URL Path'\n }\n ]\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'name',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nconst SOURCE_LINES = ['@source \"../cms/**/*.{ts,tsx}\";', '@source \"./(cms)/**/*.{ts,tsx}\";']\nconst SOURCE_LINES_SRC = ['@source \"../../cms/**/*.{ts,tsx}\";', '@source \"./(cms)/**/*.{ts,tsx}\";']\n\n// Tailwind v4 @theme tokens that map CSS vars to utility classes.\n// These let Tailwind generate bg-primary, text-muted-foreground, border-border, etc.\nconst CMS_THEME_BLOCK = `\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-input-border: var(--input-border);\n --color-ring: var(--ring);\n --color-chart-1: var(--chart-1);\n --color-chart-2: var(--chart-2);\n --color-chart-3: var(--chart-3);\n --color-chart-4: var(--chart-4);\n --color-chart-5: var(--chart-5);\n --color-sidebar: var(--sidebar);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-ring: var(--sidebar-ring);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}`\n\n/**\n * Find the main CSS file that imports Tailwind.\n */\nfunction findMainCss(cwd: string): string | undefined {\n const candidates = [\n 'src/app/globals.css',\n 'app/globals.css',\n 'src/app/global.css',\n 'app/global.css',\n 'src/app/app.css',\n 'app/app.css',\n 'src/globals.css',\n 'globals.css'\n ]\n\n for (const candidate of candidates) {\n const filePath = path.join(cwd, candidate)\n if (fs.existsSync(filePath)) {\n return filePath\n }\n }\n return undefined\n}\n\n/**\n * Append @source directive and @theme tokens to the user's main CSS file\n * so Tailwind scans CMS component classes and generates utility classes.\n */\nexport function scaffoldTailwind(\n cwd: string,\n hasSrcDir: boolean\n): { file: string | null; appended: boolean } {\n const cssFile = findMainCss(cwd)\n if (!cssFile) {\n return { file: null, appended: false }\n }\n\n let content = fs.readFileSync(cssFile, 'utf-8')\n let changed = false\n\n // 1. Add @source directives if not present\n const sourceLines = hasSrcDir ? SOURCE_LINES_SRC : SOURCE_LINES\n const missingLines = sourceLines.filter((sl) => !content.includes(sl))\n if (missingLines.length > 0) {\n const lines = content.split('\\n')\n let insertIndex = 0\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i]!.trim()\n if (\n trimmed.startsWith('@import') ||\n trimmed.startsWith('@source') ||\n trimmed.startsWith('@plugin')\n ) {\n insertIndex = i + 1\n }\n }\n lines.splice(insertIndex, 0, ...missingLines)\n content = lines.join('\\n')\n changed = true\n }\n\n // 2. Add @theme tokens if not already present\n if (!content.includes('--color-primary')) {\n // If there's an existing @theme inline block, merge into it.\n // Otherwise append the full block at the end.\n const themeMatch = content.match(/@theme\\s+inline\\s*\\{/)\n if (themeMatch && themeMatch.index !== undefined) {\n // Find the closing brace of the existing @theme block\n let braceDepth = 0\n let insertPos = -1\n for (let i = themeMatch.index; i < content.length; i++) {\n if (content[i] === '{') braceDepth++\n if (content[i] === '}') {\n braceDepth--\n if (braceDepth === 0) {\n insertPos = i\n break\n }\n }\n }\n if (insertPos !== -1) {\n // Extract the existing @theme block content to avoid duplicates\n const existingBlock = content.slice(themeMatch.index, insertPos)\n const varsOnly = CMS_THEME_BLOCK.split('\\n')\n .filter((l) => l.trim().startsWith('--'))\n .filter((l) => {\n const varName = l.trim().split(':')[0]!.trim()\n return !existingBlock.includes(varName)\n })\n .map((l) => ` ${l.trim()}`)\n .join('\\n')\n if (varsOnly) {\n content = `${content.slice(0, insertPos)}${varsOnly}\\n${content.slice(insertPos)}`\n changed = true\n }\n }\n } else {\n // No existing @theme block — append the full block\n content = `${content}\\n${CMS_THEME_BLOCK}\\n`\n changed = true\n }\n }\n\n if (changed) {\n fs.writeFileSync(cssFile, content, 'utf-8')\n }\n\n return { file: cssFile, appended: changed }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\n// Strip line and block comments from JSON, respecting quoted strings.\nfunction stripJsonComments(input: string): string {\n let result = ''\n let i = 0\n while (i < input.length) {\n // Inside a string — copy until closing quote\n if (input[i] === '\"') {\n let j = i + 1\n while (j < input.length) {\n if (input[j] === '\\\\') {\n j += 2\n continue\n }\n if (input[j] === '\"') {\n j++\n break\n }\n j++\n }\n result += input.slice(i, j)\n i = j\n // Line comment\n } else if (input[i] === '/' && input[i + 1] === '/') {\n const nl = input.indexOf('\\n', i)\n i = nl === -1 ? input.length : nl\n // Block comment\n } else if (input[i] === '/' && input[i + 1] === '*') {\n const end = input.indexOf('*/', i + 2)\n i = end === -1 ? input.length : end + 2\n } else {\n result += input[i]\n i++\n }\n }\n return result\n}\n\nconst CMS_PATH_ALIASES: Record<string, string[]> = {\n '@cms/*': ['./cms/*'],\n '@cms/db': ['./cms/db/client'],\n '@cms/db/schema': ['./cms/db/schema'],\n '@cms/actions/*': ['./cms/lib/actions/*'],\n '@cms/auth': ['./cms/lib/auth/auth'],\n '@cms/auth/client': ['./cms/lib/auth/auth-client'],\n '@cms/auth/middleware': ['./cms/lib/auth/middleware'],\n '@cms/hooks/*': ['./cms/hooks/*'],\n '@cms/components/*': ['./cms/components/*'],\n '@cms/types': ['./cms/types'],\n '@cms/types/*': ['./cms/types/*'],\n '@cms/utils/*': ['./cms/utils/*'],\n '@cms/data/*': ['./cms/data/*'],\n '@cms/cache/*': ['./cms/lib/cache/*']\n}\n\n/**\n * Append @cms/* path aliases to tsconfig.json.\n * Preserves existing content and only adds missing aliases.\n */\nexport function scaffoldTsconfig(cwd: string): { added: string[]; skipped: string[] } {\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n const added: string[] = []\n const skipped: string[] = []\n\n if (!fs.existsSync(tsconfigPath)) {\n skipped.push('tsconfig.json not found')\n return { added, skipped }\n }\n\n const raw = fs.readFileSync(tsconfigPath, 'utf-8')\n\n // Strip JSON comments while preserving string contents.\n // Walks character-by-character to avoid mangling strings that contain /* or //.\n const stripped = stripJsonComments(raw)\n // Remove trailing commas before } or ]\n .replace(/,\\s*([\\]}])/g, '$1')\n\n let tsconfig: Record<string, unknown>\n try {\n tsconfig = JSON.parse(stripped)\n } catch {\n skipped.push('Failed to parse tsconfig.json')\n return { added, skipped }\n }\n\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<string, unknown>\n const paths = (compilerOptions.paths ?? {}) as Record<string, string[]>\n\n for (const [alias, target] of Object.entries(CMS_PATH_ALIASES)) {\n if (alias in paths) {\n skipped.push(alias)\n } else {\n paths[alias] = target\n added.push(alias)\n }\n }\n\n compilerOptions.paths = paths\n tsconfig.compilerOptions = compilerOptions\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`, 'utf-8')\n\n return { added, skipped }\n}\n","/**\n * seed command — create initial admin user via Better Auth\n *\n * Generates a seed script at cms/scripts/seed.ts and runs it with tsx.\n * The script uses Better Auth's server API to create the user, then\n * sets the role to 'admin' via a direct database update.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\n\nexport function buildSeedScript(): string {\n // Self-contained: inlines DB + auth setup so tsx doesn't need @cms/* aliases.\n // Only relative import is ../db/schema which uses npm packages only.\n return `/**\n * BetterStart CMS — Seed Script\n * Creates the initial admin user\n * AUTO-GENERATED — safe to delete after running\n */\n\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\n// Load .env.local (inline — avoids @next/env dependency)\nfor (const envFile of ['.env.local', '.env']) {\n try {\n const content = readFileSync(resolve(process.cwd(), envFile), 'utf-8')\n for (const line of content.split('\\\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const eqIdx = trimmed.indexOf('=')\n if (eqIdx === -1) continue\n const key = trimmed.slice(0, eqIdx).trim()\n const val = trimmed.slice(eqIdx + 1).trim().replace(/^['\"]|['\"]$/g, '')\n if (!process.env[key]) process.env[key] = val\n }\n } catch {}\n}\n\nimport { neon } from '@neondatabase/serverless'\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport { eq } from 'drizzle-orm'\nimport * as schema from '../db/schema'\nimport { betterAuth } from 'better-auth'\nimport { drizzleAdapter } from 'better-auth/adapters/drizzle'\n\n// Inline DB connection (mirrors cms/db/client.ts)\nconst sql = neon(process.env.BETTERSTART_DATABASE_URL!)\nconst db = drizzle({ client: sql, schema })\n\n// Inline auth setup (mirrors cms/lib/auth/auth.ts)\nconst auth = betterAuth({\n secret: process.env.BETTERSTART_AUTH_SECRET,\n baseURL: process.env.BETTERSTART_AUTH_URL,\n basePath: process.env.BETTERSTART_AUTH_BASE_PATH || '/api/cms/auth',\n database: drizzleAdapter(db, {\n provider: 'pg',\n schema: {\n user: schema.user,\n session: schema.session,\n account: schema.account,\n verification: schema.verification,\n },\n }),\n emailAndPassword: { enabled: true, minPasswordLength: 8 },\n user: {\n additionalFields: {\n role: { type: 'string', required: false, defaultValue: 'member', input: false },\n },\n },\n})\n\nconst EMAIL = process.env.SEED_EMAIL!\nconst PASSWORD = process.env.SEED_PASSWORD!\nconst NAME = process.env.SEED_NAME || 'Admin'\nconst OVERWRITE = process.env.SEED_OVERWRITE === 'true'\n\nasync function main() {\n // Check if user already exists\n const existing = await db\n .select({ id: schema.user.id, name: schema.user.name })\n .from(schema.user)\n .where(eq(schema.user.email, EMAIL))\n .then((rows: { id: string; name: string }[]) => rows[0])\n\n if (existing && !OVERWRITE) {\n // Exit code 2 signals \"user exists\" to the CLI\n console.log(\\`EXISTING_USER:\\${existing.name}\\`)\n process.exit(2)\n }\n\n if (existing && OVERWRITE) {\n console.log('\\\\n Replacing existing admin user...')\n // Remove existing account + session rows first (foreign key refs)\n await db.delete(schema.session).where(eq(schema.session.userId, existing.id))\n await db.delete(schema.account).where(eq(schema.account.userId, existing.id))\n await db.delete(schema.user).where(eq(schema.user.id, existing.id))\n } else {\n console.log('\\\\n Creating admin user...')\n }\n\n console.log(\\` Email: \\${EMAIL}\\\\n\\`)\n\n const result = await auth.api.signUpEmail({\n body: { email: EMAIL, password: PASSWORD, name: NAME },\n })\n\n if (!result?.user) {\n console.error(' Failed to create user.')\n process.exit(1)\n }\n\n await db\n .update(schema.user)\n .set({ role: 'admin' })\n .where(eq(schema.user.id, result.user.id))\n\n console.log(\\` Admin user \\${existing ? 'replaced' : 'created'}: \\${EMAIL}\\`)\n console.log(' Role: admin\\\\n')\n process.exit(0)\n}\n\nmain().catch((err) => {\n console.error(' Seed failed:', err.message || err)\n process.exit(1)\n})\n`\n}\n\nexport const seedCommand = new Command('seed')\n .description('Create the initial admin user')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Seed')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n clack.cancel(`Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const cmsDir = config.paths?.cms ?? './cms'\n\n // Prompt for user details\n const email = await clack.text({\n message: 'Admin email',\n placeholder: 'admin@example.com',\n validate: (v) => {\n if (!v || !v.includes('@')) return 'Please enter a valid email'\n }\n })\n if (clack.isCancel(email)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n const password = await clack.password({\n message: 'Admin password',\n validate: (v) => {\n if (!v || v.length < 8) return 'Password must be at least 8 characters'\n }\n })\n if (clack.isCancel(password)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n const name = await clack.text({\n message: 'Admin name',\n placeholder: 'Admin',\n defaultValue: 'Admin'\n })\n if (clack.isCancel(name)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n // Write seed script\n const scriptsDir = path.join(cwd, cmsDir, 'scripts')\n const seedPath = path.join(scriptsDir, 'seed.ts')\n\n if (!fs.existsSync(scriptsDir)) {\n fs.mkdirSync(scriptsDir, { recursive: true })\n }\n fs.writeFileSync(seedPath, buildSeedScript(), 'utf-8')\n\n const { execFile } = await import('node:child_process')\n const tsxBin = path.join(cwd, 'node_modules', '.bin', 'tsx')\n\n const runSeed = (overwrite: boolean) =>\n new Promise<{ code: number; stdout: string }>((resolve, reject) => {\n execFile(\n tsxBin,\n [seedPath],\n {\n cwd,\n env: {\n ...process.env,\n SEED_EMAIL: email,\n SEED_PASSWORD: password,\n SEED_NAME: name || 'Admin',\n ...(overwrite ? { SEED_OVERWRITE: 'true' } : {})\n }\n },\n (err, stdout, stderr) => {\n if (err && 'code' in err && err.code === 2) {\n // Exit code 2 = user already exists\n resolve({ code: 2, stdout })\n } else if (err) {\n reject(new Error(stderr || err.message))\n } else {\n resolve({ code: 0, stdout })\n }\n }\n )\n })\n\n const spinner = clack.spinner()\n spinner.start('Creating admin user...')\n\n try {\n const result = await runSeed(false)\n\n if (result.code === 2) {\n // User already exists — ask to overwrite\n const existingName =\n result.stdout\n .split('\\n')\n .find((l) => l.startsWith('EXISTING_USER:'))\n ?.replace('EXISTING_USER:', '')\n ?.trim() || 'unknown'\n\n spinner.stop(`Account already exists for ${email}`)\n\n const overwrite = await clack.confirm({\n message: `An admin account (${existingName}) already exists with this email. Replace it?`\n })\n if (clack.isCancel(overwrite) || !overwrite) {\n clack.cancel('Seed cancelled.')\n // Clean up before exiting\n try {\n fs.unlinkSync(seedPath)\n } catch {}\n process.exit(0)\n }\n\n spinner.start('Replacing admin user...')\n await runSeed(true)\n spinner.stop('Admin user replaced')\n } else {\n spinner.stop('Admin user created')\n }\n } catch (err) {\n spinner.stop('Failed to create admin user')\n\n const errMsg = err instanceof Error ? err.message : String(err)\n clack.log.error(errMsg)\n clack.log.info('You can run the seed script manually:')\n clack.log.info(\n ` SEED_EMAIL=\"${email}\" SEED_PASSWORD=\"...\" npx tsx ${path.relative(cwd, seedPath)}`\n )\n clack.outro('')\n process.exit(1)\n }\n\n // Clean up seed script\n try {\n fs.unlinkSync(seedPath)\n // Remove scripts dir if empty\n if (fs.existsSync(scriptsDir) && fs.readdirSync(scriptsDir).length === 0) {\n fs.rmdirSync(scriptsDir)\n }\n } catch {\n // Not critical\n }\n\n clack.outro(`Admin user ready: ${email}`)\n })\n","/**\n * remove command — delete generated files, clean schema.ts + navigation.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport readline from 'node:readline'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport { toCamelCase, singularize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Schema.ts Cleaning\n// ============================================================================\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n // Skip trailing newlines\n let end = i + 1\n while (end < content.length && content[end] === '\\n') end++\n return end\n }\n }\n return content.length\n}\n\nfunction removeTableFromSchema(schemaFilePath: string, name: string): boolean {\n if (!fs.existsSync(schemaFilePath)) return false\n\n let content = fs.readFileSync(schemaFilePath, 'utf-8')\n const variableName = toCamelCase(name)\n let changed = false\n\n // Remove main table\n if (content.includes(`export const ${variableName} =`)) {\n const start = content.indexOf(`export const ${variableName} =`)\n const end = findTableEnd(content, start)\n content = content.slice(0, start) + content.slice(end)\n changed = true\n }\n\n // Remove junction tables (e.g., postCategories for posts schema)\n const singular = singularize(name)\n const junctionPrefix = toCamelCase(singular)\n // Find all exports starting with the singular prefix that are pgTable calls\n const regex = new RegExp(`export const (${junctionPrefix}[A-Z]\\\\w*) = pgTable\\\\(`, 'g')\n let jMatch = regex.exec(content)\n while (jMatch) {\n const jVarName = jMatch[1]\n const jStart = content.indexOf(`export const ${jVarName} =`)\n if (jStart !== -1) {\n const jEnd = findTableEnd(content, jStart)\n content = content.slice(0, jStart) + content.slice(jEnd)\n changed = true\n // Reset regex since content changed\n regex.lastIndex = 0\n jMatch = regex.exec(content)\n } else {\n jMatch = regex.exec(content)\n }\n }\n\n if (changed) {\n // Clean up multiple blank lines\n content = content.replace(/\\n{3,}/g, '\\n\\n')\n fs.writeFileSync(schemaFilePath, content, 'utf-8')\n }\n\n return changed\n}\n\n// ============================================================================\n// Navigation.ts Cleaning\n// ============================================================================\n\nfunction removeFromNavigation(navFilePath: string, name: string): boolean {\n if (!fs.existsSync(navFilePath)) return false\n\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const href = `/cms/${name}`\n\n if (!content.includes(`'${href}'`)) return false\n\n // Flat structure: find the { ... } block containing this href\n const lines = content.split('\\n')\n let startLine = -1\n let endLine = -1\n let depth = 0\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n\n if (startLine === -1 && line.includes(`'${href}'`)) {\n // Walk back to find the opening `{`\n for (let j = i; j >= 0; j--) {\n if (lines[j].trim().startsWith('{')) {\n startLine = j\n break\n }\n }\n }\n\n if (startLine !== -1 && i >= startLine) {\n for (const char of line) {\n if (char === '{') depth++\n if (char === '}') depth--\n }\n if (depth === 0 && line.includes('}')) {\n endLine = i\n break\n }\n }\n }\n\n if (startLine === -1 || endLine === -1) return false\n\n lines.splice(startLine, endLine - startLine + 1)\n\n // Clean up double commas or leading commas\n const updated = lines\n .join('\\n')\n .replace(/,\\s*,/g, ',')\n .replace(/\\[\\s*,/, '[')\n fs.writeFileSync(navFilePath, updated, 'utf-8')\n return true\n}\n\n// ============================================================================\n// Confirmation\n// ============================================================================\n\nasync function promptConfirm(message: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n })\n return new Promise((resolve) => {\n rl.question(`${message} (y/N) `, (answer) => {\n rl.close()\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes')\n })\n })\n}\n\n// ============================================================================\n// Command\n// ============================================================================\n\nexport const removeCommand = new Command('remove')\n .alias('rm')\n .description('Remove all generated files for an entity or form')\n .argument('<schema>', 'Schema name to remove (e.g. posts, categories, contact)')\n .option('-f, --force', 'Skip confirmation prompt', false)\n .option('--cwd <path>', 'Project root path')\n .action(async (schemaName: string, options: { force: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n console.log('\\n BetterStart Remove\\n')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const cmsDir = config.paths?.cms ?? './cms'\n const pagesDir = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n const kebabName = toKebabCase(schemaName)\n\n // Collect files/dirs to remove\n const targets: { path: string; label: string; isDir: boolean }[] = []\n\n // Pages directory\n const entityPagesDir = path.join(cwd, pagesDir, schemaName)\n if (fs.existsSync(entityPagesDir)) {\n targets.push({\n path: entityPagesDir,\n label: `${path.join(pagesDir, schemaName)}/`,\n isDir: true\n })\n }\n\n // Actions directory (new format) or single file (legacy format)\n const actionsDir = path.join(cwd, cmsDir, 'lib', 'actions', kebabName)\n const actionsFile = path.join(cwd, cmsDir, 'lib', 'actions', `${kebabName}.ts`)\n if (fs.existsSync(actionsDir)) {\n targets.push({\n path: actionsDir,\n label: `${path.join(cmsDir, 'lib', 'actions', kebabName)}/`,\n isDir: true\n })\n } else if (fs.existsSync(actionsFile)) {\n targets.push({\n path: actionsFile,\n label: path.join(cmsDir, 'lib', 'actions', `${kebabName}.ts`),\n isDir: false\n })\n }\n\n // Hook file\n const hookFile = path.join(cwd, cmsDir, 'hooks', `use-${kebabName}.ts`)\n if (fs.existsSync(hookFile)) {\n targets.push({\n path: hookFile,\n label: path.join(cmsDir, 'hooks', `use-${kebabName}.ts`),\n isDir: false\n })\n }\n\n // Check schema.ts for table entry\n const schemaFilePath = path.join(cwd, cmsDir, 'db', 'schema.ts')\n const hasTable =\n fs.existsSync(schemaFilePath) &&\n fs.readFileSync(schemaFilePath, 'utf-8').includes(`export const ${toCamelCase(schemaName)} =`)\n\n // Check navigation.ts for entry\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n const hasNavEntry =\n fs.existsSync(navFilePath) &&\n fs.readFileSync(navFilePath, 'utf-8').includes(`'/cms/${schemaName}'`)\n\n if (targets.length === 0 && !hasTable && !hasNavEntry) {\n console.log(` No generated files found for: ${schemaName}`)\n return\n }\n\n // Show what will be removed\n console.log(' Files to remove:\\n')\n for (const t of targets) {\n console.log(` ${t.isDir ? '[dir]' : ' '} ${t.label}`)\n }\n if (hasTable) {\n console.log(` [edit] ${path.join(cmsDir, 'db', 'schema.ts')} (remove table)`)\n }\n if (hasNavEntry) {\n console.log(` [edit] ${path.join(cmsDir, 'data', 'navigation.ts')} (remove entry)`)\n }\n\n // Confirm\n if (!options.force) {\n console.log('')\n const confirmed = await promptConfirm(' Are you sure?')\n if (!confirmed) {\n console.log('\\n Cancelled.\\n')\n return\n }\n }\n\n console.log('')\n\n // Delete files/dirs\n for (const t of targets) {\n if (t.isDir) {\n fs.rmSync(t.path, { recursive: true, force: true })\n } else {\n fs.unlinkSync(t.path)\n }\n console.log(` Removed: ${t.label}`)\n }\n\n // Clean schema.ts\n if (hasTable) {\n removeTableFromSchema(schemaFilePath, schemaName)\n console.log(` Cleaned: ${path.join(cmsDir, 'db', 'schema.ts')}`)\n }\n\n // Clean navigation.ts\n if (hasNavEntry) {\n removeFromNavigation(navFilePath, schemaName)\n console.log(` Cleaned: ${path.join(cmsDir, 'data', 'navigation.ts')}`)\n }\n\n console.log('\\n Removal complete!')\n console.log('\\n Note: You may need to manually:')\n console.log(' - Run a migration to drop the database table')\n console.log(' - Remove the schema file from cms/schemas/')\n console.log(' - Regenerate the cache module (betterstart generate <any-schema>)')\n console.log('')\n })\n","/**\n * setup-r2 command — create a Cloudflare R2 bucket and configure env vars\n *\n * 1. Checks for wrangler CLI\n * 2. Ensures user is logged in to Cloudflare\n * 3. Creates an R2 bucket\n * 4. Enables the r2.dev public URL automatically via CF API\n * 5. Opens the dashboard for API token creation\n * 6. Prompts for credentials and writes them to .env.local\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\n\nimport { appendEnvVars } from '../utils/env.js'\n\nexport const setupR2Command = new Command('setup-r2')\n .description('Create a Cloudflare R2 bucket and configure storage env vars')\n .option('--cwd <path>', 'Project root path')\n .option('--bucket <name>', 'Bucket name (skips prompt)')\n .action(async (options: { cwd?: string; bucket?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n p.intro(pc.bgCyan(pc.black(' BetterStart — R2 Storage Setup ')))\n\n const s = p.spinner()\n\n // 1. Check for wrangler\n s.start('Looking for wrangler CLI')\n const wrangler = findWrangler(cwd)\n if (!wrangler) {\n s.stop(`${pc.red('✗')} Wrangler CLI not found`)\n p.log.error(\n `Install it first:\\n ${pc.cyan('npm install -g wrangler')}\\n ${pc.dim('or')} ${pc.cyan('npx wrangler --version')}`\n )\n process.exit(1)\n }\n s.stop(`Wrangler: ${pc.cyan(wrangler.bin === 'npx' ? 'npx wrangler' : 'wrangler')}`)\n\n // 2. Check auth / prompt login\n s.start('Checking Cloudflare authentication')\n const whoami = runWrangler(wrangler, ['whoami'], { cwd })\n const whoamiOut = whoami.stdout?.toString() ?? ''\n\n if (whoami.status !== 0 || whoamiOut.includes('Not authenticated')) {\n s.stop(`${pc.yellow('▲')} Not logged in to Cloudflare`)\n const login = await p.confirm({\n message: 'Open browser to log in to Cloudflare?',\n initialValue: true,\n })\n if (p.isCancel(login) || !login) {\n p.cancel('Setup cancelled. Run `wrangler login` manually first.')\n process.exit(0)\n }\n\n s.start('Waiting for Cloudflare login')\n const loginResult = runWrangler(wrangler, ['login'], { cwd, stdio: 'inherit', timeout: 120_000 })\n if (loginResult.status !== 0) {\n s.stop(`${pc.red('✗')} Login failed`)\n p.cancel('Could not authenticate with Cloudflare. Run `wrangler login` manually.')\n process.exit(1)\n }\n s.stop(`${pc.green('✓')} Logged in to Cloudflare`)\n } else {\n // Table format: \"│ Peiris@kasun.io's Account │ <id> │\"\n // Or \"associated with the email user@example.com\"\n const emailMatch = whoamiOut.match(/associated with the email\\s+(\\S+)/i)\n const tableMatch = whoamiOut.match(/│\\s*([^│]+?)\\s*│\\s*[a-f0-9]{32}\\s*│/)\n const accountLabel = emailMatch?.[1] ?? tableMatch?.[1]?.trim() ?? 'authenticated'\n s.stop(`Logged in as ${pc.cyan(accountLabel)}`)\n }\n\n // 3. Get account ID\n s.start('Fetching account ID')\n const accountId = extractAccountId(wrangler, cwd)\n if (!accountId) {\n s.stop(`${pc.red('✗')} Could not determine account ID`)\n p.log.info(\n `You can find it at: ${pc.cyan('https://dash.cloudflare.com/?to=/:account/r2')}`\n )\n process.exit(1)\n }\n s.stop(`Account ID: ${pc.dim(accountId)}`)\n\n // 4. Prompt for bucket name\n let bucketName = options.bucket\n if (!bucketName) {\n const result = await p.text({\n message: 'R2 bucket name',\n placeholder: 'betterstart-uploads',\n defaultValue: 'betterstart-uploads',\n validate: (v) => {\n if (!v || v.length < 3) return 'Bucket name must be at least 3 characters'\n if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(v))\n return 'Bucket name must be lowercase alphanumeric with hyphens, no leading/trailing hyphens'\n },\n })\n if (p.isCancel(result)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n bucketName = result\n }\n\n // 5. Create bucket\n s.start(`Creating R2 bucket: ${bucketName}`)\n\n const createResult = runWrangler(wrangler, ['r2', 'bucket', 'create', bucketName], {\n cwd,\n timeout: 30_000,\n })\n const createOut = (createResult.stdout?.toString() ?? '') + (createResult.stderr?.toString() ?? '')\n\n if (createResult.status !== 0) {\n if (createOut.includes('already exists') || createOut.includes('AlreadyExists')) {\n s.stop(`Bucket ${pc.cyan(bucketName)} already exists — using it`)\n } else {\n s.stop('Failed to create bucket')\n p.log.error(createOut.trim() || 'Unknown error from wrangler')\n process.exit(1)\n }\n } else {\n s.stop(`Created bucket: ${pc.cyan(bucketName)}`)\n }\n\n // 6. Enable r2.dev public URL automatically\n let publicUrl = ''\n const oauthToken = readWranglerToken()\n if (oauthToken) {\n s.start('Enabling public r2.dev URL')\n const domainResult = await enablePublicDomain(accountId, bucketName, oauthToken)\n if (domainResult.success && domainResult.domain) {\n publicUrl = `https://${domainResult.domain}`\n s.stop(`Public URL: ${pc.cyan(publicUrl)}`)\n } else {\n s.stop('Could not enable public URL automatically')\n p.log.warning(domainResult.error ?? 'Unknown error')\n p.log.info(\n `You can enable it manually in the dashboard:\\n ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/default/buckets/${bucketName}/settings`)}`\n )\n }\n } else {\n p.log.warning('Could not read wrangler OAuth token — skipping public URL setup')\n p.log.info(\n `Enable it manually: ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/default/buckets/${bucketName}/settings`)}`\n )\n }\n\n // 7. Prompt for S3-compatible API credentials\n p.note(\n [\n `Create an R2 API token with ${pc.bold('Object Read & Write')} permission.`,\n '',\n `Dashboard: ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/api-tokens`)}`,\n '',\n pc.dim('The dashboard will give you an Access Key ID and Secret Access Key.'),\n ].join('\\n'),\n 'Create R2 API Token'\n )\n\n const openDashboard = await p.confirm({\n message: 'Open the R2 API tokens page in your browser?',\n initialValue: true,\n })\n if (!p.isCancel(openDashboard) && openDashboard) {\n const url = `https://dash.cloudflare.com/${accountId}/r2/api-tokens`\n try {\n execFileSync('open', [url], { stdio: 'pipe', timeout: 5_000 })\n } catch {\n p.log.warning(`Could not open browser. Visit: ${pc.cyan(url)}`)\n }\n }\n\n const credentials = await p.group(\n {\n accessKeyId: () =>\n p.text({\n message: 'R2 Access Key ID',\n placeholder: 'Paste from Cloudflare dashboard',\n validate: (v) => {\n if (!v || v.trim().length < 10) return 'Please paste a valid Access Key ID'\n },\n }),\n secretAccessKey: () =>\n p.password({\n message: 'R2 Secret Access Key',\n validate: (v) => {\n if (!v || v.trim().length < 10) return 'Please paste a valid Secret Access Key'\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel('Setup cancelled.')\n process.exit(0)\n },\n }\n )\n\n // 8. Write env vars to .env.local\n s.start('Writing environment variables')\n const envResult = appendEnvVars(cwd, [\n {\n header: 'Storage (Cloudflare R2)',\n vars: [\n { key: 'BETTERSTART_R2_ACCOUNT_ID', value: accountId },\n { key: 'BETTERSTART_R2_ACCESS_KEY_ID', value: credentials.accessKeyId.trim() },\n { key: 'BETTERSTART_R2_SECRET_ACCESS_KEY', value: credentials.secretAccessKey.trim() },\n { key: 'BETTERSTART_R2_BUCKET_NAME', value: bucketName },\n ...(publicUrl ? [{ key: 'BETTERSTART_R2_PUBLIC_URL', value: publicUrl }] : []),\n ],\n },\n ], new Set([\n 'BETTERSTART_R2_ACCOUNT_ID',\n 'BETTERSTART_R2_ACCESS_KEY_ID',\n 'BETTERSTART_R2_SECRET_ACCESS_KEY',\n 'BETTERSTART_R2_BUCKET_NAME',\n 'BETTERSTART_R2_PUBLIC_URL',\n ]))\n\n const totalChanged = envResult.added.length + envResult.updated.length\n if (totalChanged > 0) {\n s.stop(`Updated .env.local ${pc.dim(`(${envResult.added.length} added, ${envResult.updated.length} updated)`)}`)\n } else {\n s.stop('All R2 env vars already set in .env.local')\n }\n\n // Summary\n const summaryLines = [\n `Bucket: ${pc.cyan(bucketName)}`,\n `Account: ${pc.dim(accountId)}`,\n `Access Key: ${pc.dim(credentials.accessKeyId.trim().slice(0, 8) + '...')}`,\n ]\n if (publicUrl) {\n summaryLines.push(`Public URL: ${pc.cyan(publicUrl)}`)\n }\n summaryLines.push(`Env file: ${pc.dim('.env.local')}`)\n\n p.note(summaryLines.join('\\n'), pc.green('R2 storage configured'))\n\n p.outro('Done! Your CMS can now upload files to R2.')\n })\n\ninterface WranglerRef {\n bin: string\n prefix: string[] // e.g. ['wrangler'] when using npx, [] when direct\n}\n\n/** Find wrangler binary — check local node_modules, global PATH, then npx */\nfunction findWrangler(cwd: string): WranglerRef | null {\n // Check local\n const localBin = path.join(cwd, 'node_modules', '.bin', 'wrangler')\n if (fs.existsSync(localBin)) return { bin: localBin, prefix: [] }\n\n // Check global via which\n const result = spawnSync('which', ['wrangler'], { stdio: 'pipe', timeout: 5_000 })\n if (result.status === 0) {\n const found = result.stdout?.toString().trim()\n if (found) return { bin: found, prefix: [] }\n }\n\n // Fall back to npx — just check it resolves (fast, no download)\n const npxResult = spawnSync('npx', ['wrangler', '--version'], {\n stdio: 'pipe',\n timeout: 15_000,\n })\n if (npxResult.status === 0) return { bin: 'npx', prefix: ['wrangler'] }\n\n return null\n}\n\n/** Run a wrangler command via the resolved ref */\nfunction runWrangler(\n ref: WranglerRef,\n args: string[],\n opts: { cwd: string; timeout?: number; stdio?: 'pipe' | 'inherit' }\n) {\n const fullArgs = [...ref.prefix, ...args]\n return spawnSync(ref.bin, fullArgs, {\n cwd: opts.cwd,\n stdio: opts.stdio ?? 'pipe',\n timeout: opts.timeout ?? 15_000,\n })\n}\n\n/** Extract account ID from wrangler whoami output */\nfunction extractAccountId(ref: WranglerRef, cwd: string): string | null {\n const result = runWrangler(ref, ['whoami'], { cwd })\n const output = result.stdout?.toString() ?? ''\n\n // wrangler whoami prints account ID in format: \"Account ID: <id>\"\n const idMatch = output.match(/Account ID[:\\s]+([a-f0-9]{32})/i)\n if (idMatch) return idMatch[1]\n\n // Table format: look for 32-char hex string\n const hexMatch = output.match(/\\b([a-f0-9]{32})\\b/)\n if (hexMatch) return hexMatch[1]\n\n return null\n}\n\n/** Read the OAuth token from wrangler's config file */\nfunction readWranglerToken(): string | null {\n // Wrangler stores config at platform-specific paths\n const candidates = [\n path.join(os.homedir(), 'Library', 'Preferences', '.wrangler', 'config', 'default.toml'), // macOS\n path.join(os.homedir(), '.config', '.wrangler', 'config', 'default.toml'), // Linux\n path.join(os.homedir(), '.wrangler', 'config', 'default.toml'), // fallback\n ]\n\n if (process.env.WRANGLER_CONFIG_PATH) {\n candidates.unshift(process.env.WRANGLER_CONFIG_PATH)\n }\n if (process.env.XDG_CONFIG_HOME) {\n candidates.unshift(\n path.join(process.env.XDG_CONFIG_HOME, '.wrangler', 'config', 'default.toml')\n )\n }\n\n for (const configPath of candidates) {\n if (!fs.existsSync(configPath)) continue\n try {\n const content = fs.readFileSync(configPath, 'utf-8')\n const match = content.match(/^oauth_token\\s*=\\s*\"([^\"]+)\"/m)\n if (match) return match[1]\n } catch {\n continue\n }\n }\n return null\n}\n\n/** Enable the r2.dev managed public domain on a bucket via Cloudflare API */\nasync function enablePublicDomain(\n accountId: string,\n bucketName: string,\n token: string\n): Promise<{ success: boolean; domain?: string; error?: string }> {\n try {\n const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/domains/managed`\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ enabled: true }),\n })\n const data = (await res.json()) as {\n success: boolean\n result?: { domain?: string; enabled?: boolean }\n errors?: Array<{ message: string }>\n }\n if (data.success && data.result?.domain) {\n return { success: true, domain: data.result.domain }\n }\n const errMsg = data.errors?.[0]?.message ?? 'API returned success=false'\n return { success: false, error: errMsg }\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : 'fetch failed' }\n }\n}\n","/**\n * uninstall command — fully reverse everything `betterstart init` did.\n * Removes CMS directories, config files, path aliases, CSS modifications,\n * env vars, and dependencies from package.json.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\nimport { cleanCss, cleanEnvFile, cleanTsconfig } from './uninstall-cleaners.js'\n\n// ============================================================================\n// CSS File Finder (shared logic with tailwind scaffolder)\n// ============================================================================\n\nfunction findMainCss(cwd: string): string | undefined {\n const candidates = [\n 'src/app/globals.css',\n 'app/globals.css',\n 'src/app/global.css',\n 'app/global.css',\n 'src/app/app.css',\n 'app/app.css',\n 'src/globals.css',\n 'globals.css'\n ]\n for (const candidate of candidates) {\n const filePath = path.join(cwd, candidate)\n if (fs.existsSync(filePath)) return filePath\n }\n return undefined\n}\n\n// ============================================================================\n// Biome Detection\n// ============================================================================\n\nfunction isCLICreatedBiome(biomePath: string): boolean {\n if (!fs.existsSync(biomePath)) return false\n try {\n const content = JSON.parse(fs.readFileSync(biomePath, 'utf-8'))\n // Check key structural markers that match our template\n return (\n content.$schema?.includes('biomejs.dev') &&\n content.formatter?.indentStyle === 'space' &&\n content.javascript?.formatter?.quoteStyle === 'single' &&\n Array.isArray(content.files?.ignore) &&\n content.files.ignore.includes('.next')\n )\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// Uninstall Plan\n// ============================================================================\n\ninterface UninstallStep {\n label: string\n items: string[]\n count: number\n unit: string\n execute: () => void\n}\n\nfunction buildUninstallPlan(cwd: string): UninstallStep[] {\n const steps: UninstallStep[] = []\n const hasSrc = fs.existsSync(path.join(cwd, 'src'))\n const appBase = hasSrc ? 'src/app' : 'app'\n\n // Step 1: CMS directories\n const dirs: string[] = []\n const cmsDir = path.join(cwd, 'cms')\n const cmsRouteGroup = path.join(cwd, appBase, '(cms)')\n if (fs.existsSync(cmsDir)) dirs.push('cms/')\n if (fs.existsSync(cmsRouteGroup)) dirs.push(`${appBase}/(cms)/`)\n\n if (dirs.length > 0) {\n steps.push({\n label: 'CMS directories',\n items: dirs,\n count: dirs.length,\n unit: dirs.length === 1 ? 'directory' : 'directories',\n execute() {\n if (fs.existsSync(cmsDir)) fs.rmSync(cmsDir, { recursive: true, force: true })\n if (fs.existsSync(cmsRouteGroup)) fs.rmSync(cmsRouteGroup, { recursive: true, force: true })\n }\n })\n }\n\n // Step 2: Config files\n const configFiles: string[] = []\n const configPaths: string[] = []\n const candidates = [\n ['cms.config.ts', path.join(cwd, 'cms.config.ts')],\n ['drizzle.config.ts', path.join(cwd, 'drizzle.config.ts')],\n ['CMS.md', path.join(cwd, 'CMS.md')]\n ] as const\n\n for (const [label, fullPath] of candidates) {\n if (fs.existsSync(fullPath)) {\n configFiles.push(label)\n configPaths.push(fullPath)\n }\n }\n\n const biomePath = path.join(cwd, 'biome.json')\n if (isCLICreatedBiome(biomePath)) {\n configFiles.push('biome.json (CLI-created)')\n configPaths.push(biomePath)\n }\n\n if (configFiles.length > 0) {\n steps.push({\n label: 'Config files',\n items: configFiles,\n count: configFiles.length,\n unit: configFiles.length === 1 ? 'file' : 'files',\n execute() {\n for (const p of configPaths) {\n if (fs.existsSync(p)) fs.unlinkSync(p)\n }\n }\n })\n }\n\n // Step 3: tsconfig.json @cms/* aliases\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n if (fs.existsSync(tsconfigPath)) {\n const content = fs.readFileSync(tsconfigPath, 'utf-8')\n const aliasMatches = content.match(/\"@cms\\//g)\n if (aliasMatches && aliasMatches.length > 0) {\n const aliasCount = aliasMatches.length\n steps.push({\n label: 'tsconfig.json path aliases',\n items: [`@cms/* aliases in tsconfig.json`],\n count: aliasCount,\n unit: aliasCount === 1 ? 'alias' : 'aliases',\n execute() {\n cleanTsconfig(tsconfigPath)\n }\n })\n }\n }\n\n // Step 4: CSS @source lines\n const cssFile = findMainCss(cwd)\n if (cssFile) {\n const cssContent = fs.readFileSync(cssFile, 'utf-8')\n const sourceLines = cssContent\n .split('\\n')\n .filter((l) => /^@source\\s+\"[^\"]*cms[^\"]*\";\\s*$/.test(l))\n if (sourceLines.length > 0) {\n const relCss = path.relative(cwd, cssFile)\n steps.push({\n label: `CSS @source lines (${relCss})`,\n items: [`@source lines in ${relCss}`],\n count: sourceLines.length,\n unit: sourceLines.length === 1 ? 'line' : 'lines',\n execute() {\n cleanCss(cssFile)\n }\n })\n }\n }\n\n // Step 5: .env.local BETTERSTART_* vars\n const envPath = path.join(cwd, '.env.local')\n if (fs.existsSync(envPath)) {\n const envContent = fs.readFileSync(envPath, 'utf-8')\n const bsVars = envContent\n .split('\\n')\n .filter((l) => l.trim().match(/^BETTERSTART_\\w+=/))\n .map((l) => l.split('=')[0]!)\n if (bsVars.length > 0) {\n steps.push({\n label: '.env.local variables',\n items: ['BETTERSTART_* vars in .env.local'],\n count: bsVars.length,\n unit: bsVars.length === 1 ? 'variable' : 'variables',\n execute() {\n cleanEnvFile(envPath)\n }\n })\n }\n }\n\n return steps\n}\n\n// ============================================================================\n// Command\n// ============================================================================\n\nexport const uninstallCommand = new Command('uninstall')\n .description('Remove all CMS files and undo modifications made by betterstart init')\n .option('-f, --force', 'Skip all confirmation prompts', false)\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { force: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n p.intro(pc.bgRed(pc.white(' BetterStart Uninstall ')))\n\n // Build the plan\n const steps = buildUninstallPlan(cwd)\n\n if (steps.length === 0) {\n p.log.success(`${pc.green('✓')} Nothing to remove — project is already clean.`)\n p.outro('Done')\n return\n }\n\n // Show plan as a formatted note box\n const planLines = steps.map((step) => {\n const names = step.items.join(' ')\n const countLabel = pc.dim(`${step.count} ${step.unit}`)\n return `${pc.red('×')} ${names} ${countLabel}`\n })\n p.note(planLines.join('\\n'), 'Uninstall plan')\n\n // Single confirmation for everything\n if (!options.force) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n initialValue: false\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Uninstall cancelled.')\n process.exit(0)\n }\n }\n\n // Execute all steps with a single spinner\n const s = p.spinner()\n s.start(steps[0]!.label)\n for (const step of steps) {\n s.message(step.label)\n step.execute()\n }\n const parts = steps.map((step) => `${step.count} ${step.unit}`)\n s.stop(`Removed ${parts.join(', ')}`)\n\n p.note(pc.dim('Database tables were NOT dropped — drop them manually if needed.'), 'Next steps')\n\n p.outro('Uninstall complete')\n })\n","/**\n * Cleaner functions for `betterstart uninstall`.\n * Each function modifies a single file type and returns what was removed.\n */\n\nimport fs from 'node:fs'\n\n// ============================================================================\n// JSON Comment Stripper (shared with tsconfig scaffolder)\n// ============================================================================\n\nfunction stripJsonComments(input: string): string {\n let result = ''\n let i = 0\n while (i < input.length) {\n if (input[i] === '\"') {\n let j = i + 1\n while (j < input.length) {\n if (input[j] === '\\\\') {\n j += 2\n continue\n }\n if (input[j] === '\"') {\n j++\n break\n }\n j++\n }\n result += input.slice(i, j)\n i = j\n } else if (input[i] === '/' && input[i + 1] === '/') {\n const nl = input.indexOf('\\n', i)\n i = nl === -1 ? input.length : nl\n } else if (input[i] === '/' && input[i + 1] === '*') {\n const end = input.indexOf('*/', i + 2)\n i = end === -1 ? input.length : end + 2\n } else {\n result += input[i]\n i++\n }\n }\n return result\n}\n\n// ============================================================================\n// cleanTsconfig\n// ============================================================================\n\n/**\n * Remove all `@cms/*` path aliases from tsconfig.json.\n * Returns the list of removed alias keys.\n */\nexport function cleanTsconfig(tsconfigPath: string): string[] {\n if (!fs.existsSync(tsconfigPath)) return []\n\n const raw = fs.readFileSync(tsconfigPath, 'utf-8')\n const stripped = stripJsonComments(raw).replace(/,\\s*([\\]}])/g, '$1')\n\n let tsconfig: Record<string, unknown>\n try {\n tsconfig = JSON.parse(stripped)\n } catch {\n return []\n }\n\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<string, unknown>\n const paths = (compilerOptions.paths ?? {}) as Record<string, string[]>\n\n const removed: string[] = []\n for (const key of Object.keys(paths)) {\n if (key.startsWith('@cms/') || key === '@cms/*') {\n removed.push(key)\n delete paths[key]\n }\n }\n\n if (removed.length === 0) return []\n\n if (Object.keys(paths).length === 0) {\n compilerOptions.paths = undefined\n } else {\n compilerOptions.paths = paths\n }\n tsconfig.compilerOptions = compilerOptions\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`, 'utf-8')\n return removed\n}\n\n// ============================================================================\n// cleanCss\n// ============================================================================\n\n/**\n * Remove @source lines containing \"cms\" from a CSS file.\n * Returns the removed lines.\n */\nexport function cleanCss(cssPath: string): string[] {\n if (!fs.existsSync(cssPath)) return []\n\n const content = fs.readFileSync(cssPath, 'utf-8')\n const lines = content.split('\\n')\n\n const sourcePattern = /^@source\\s+\"[^\"]*cms[^\"]*\";\\s*$/\n const removed: string[] = []\n const kept: string[] = []\n\n for (const line of lines) {\n if (sourcePattern.test(line)) {\n removed.push(line.trim())\n } else {\n kept.push(line)\n }\n }\n\n if (removed.length === 0) return []\n\n // Clean up resulting double blank lines\n const cleaned = kept.join('\\n').replace(/\\n{3,}/g, '\\n\\n')\n fs.writeFileSync(cssPath, cleaned, 'utf-8')\n return removed\n}\n\n// ============================================================================\n// cleanEnvFile\n// ============================================================================\n\n/**\n * Remove BETTERSTART_* vars and the BetterStart header block from .env.local.\n * Returns the removed variable names.\n */\nexport function cleanEnvFile(envPath: string): string[] {\n if (!fs.existsSync(envPath)) return []\n\n const content = fs.readFileSync(envPath, 'utf-8')\n const lines = content.split('\\n')\n const removed: string[] = []\n const kept: string[] = []\n\n // Track header block lines to remove\n const headerPattern = /^# =+$/\n const headerTextPattern = /^# BetterStart CMS$/\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const trimmed = line.trim()\n\n // Remove BETTERSTART_* variable lines\n if (trimmed.match(/^BETTERSTART_\\w+=/)) {\n const key = trimmed.split('=')[0]!\n removed.push(key)\n continue\n }\n\n // Remove header block: # ====... / # BetterStart CMS / # ====...\n if (headerPattern.test(trimmed)) {\n const next = lines[i + 1]?.trim()\n const afterNext = lines[i + 2]?.trim()\n if (next && headerTextPattern.test(next) && afterNext && headerPattern.test(afterNext)) {\n i += 2 // skip all 3 header lines\n continue\n }\n }\n\n // Remove section comment headers that only precede BETTERSTART_ vars\n // e.g., \"# Database (Neon)\" followed by BETTERSTART_DATABASE_URL\n if (trimmed.startsWith('#') && !headerPattern.test(trimmed)) {\n const nextNonEmpty = findNextNonEmptyLine(lines, i + 1)\n if (nextNonEmpty?.match(/^BETTERSTART_\\w+=/)) {\n continue // skip this comment header\n }\n }\n\n kept.push(line)\n }\n\n if (removed.length === 0) return []\n\n // Clean up multiple blank lines\n const result = kept\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\n if (result === '') {\n // File is now empty — delete it\n fs.unlinkSync(envPath)\n } else {\n fs.writeFileSync(envPath, `${result}\\n`, 'utf-8')\n }\n\n return removed\n}\n\nfunction findNextNonEmptyLine(lines: string[], startIndex: number): string | null {\n for (let i = startIndex; i < lines.length; i++) {\n const trimmed = lines[i]!.trim()\n if (trimmed !== '') return trimmed\n }\n return null\n}\n\n// ============================================================================\n// cleanPackageJsonDeps\n// ============================================================================\n\n/**\n * Remove CMS dependencies from package.json.\n * Returns the removed dep and devDep names.\n */\nexport function cleanPackageJsonDeps(\n pkgPath: string,\n allDeps: string[],\n allDevDeps: string[]\n): { removed: string[]; removedDev: string[] } {\n if (!fs.existsSync(pkgPath)) return { removed: [], removedDev: [] }\n\n const content = fs.readFileSync(pkgPath, 'utf-8')\n let pkg: Record<string, unknown>\n try {\n pkg = JSON.parse(content)\n } catch {\n return { removed: [], removedDev: [] }\n }\n\n const deps = (pkg.dependencies ?? {}) as Record<string, string>\n const devDeps = (pkg.devDependencies ?? {}) as Record<string, string>\n\n // Build lookup set: handle version-pinned names like @types/markdown-it@13 → @types/markdown-it\n const depNames = new Set(\n allDeps.map((d) =>\n d\n .split('@')\n .slice(0, d.startsWith('@') ? 2 : 1)\n .join('@')\n )\n )\n const devDepNames = new Set(\n allDevDeps.map((d) =>\n d\n .split('@')\n .slice(0, d.startsWith('@') ? 2 : 1)\n .join('@')\n )\n )\n\n const removed: string[] = []\n for (const name of Object.keys(deps)) {\n if (depNames.has(name)) {\n delete deps[name]\n removed.push(name)\n }\n }\n\n const removedDev: string[] = []\n for (const name of Object.keys(devDeps)) {\n if (devDepNames.has(name)) {\n delete devDeps[name]\n removedDev.push(name)\n }\n }\n\n if (removed.length === 0 && removedDev.length === 0) {\n return { removed: [], removedDev: [] }\n }\n\n pkg.dependencies = deps\n pkg.devDependencies = devDeps\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`, 'utf-8')\n\n return { removed, removedDev }\n}\n","/**\n * update-component command — update individual CMS components from the latest CLI templates\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport fsExtra from 'fs-extra'\nimport { resolveConfig } from '../config/resolver.js'\nimport { readTemplate } from '../init/templates/reader.js'\nimport { findCliRoot } from '../utils/cli-root.js'\n\ninterface TemplateEntry {\n relPath: string\n content: () => string\n base?: 'cwd'\n}\n\n/**\n * Template-function components (layout, shared, hooks, utils, etc.)\n * Key = component name used on CLI, value = { relative path in cms/, content generator }\n */\nconst TEMPLATE_REGISTRY: Record<string, TemplateEntry> = {\n // CSS\n 'cms-globals': { relPath: 'cms-globals.css', content: () => readTemplate('cms-globals.css') },\n // Layout\n 'cms-providers': { relPath: 'components/layout/cms-providers.tsx', content: () => readTemplate('components/layout/cms-providers.tsx') },\n 'cms-nav-link': { relPath: 'components/layout/cms-nav-link.tsx', content: () => readTemplate('components/layout/cms-nav-link.tsx') },\n 'cms-sidebar': { relPath: 'components/layout/cms-sidebar.tsx', content: () => readTemplate('components/layout/cms-sidebar.tsx') },\n 'cms-header': { relPath: 'components/layout/cms-header.tsx', content: () => readTemplate('components/layout/cms-header.tsx') },\n 'cms-search': { relPath: 'components/layout/cms-search.tsx', content: () => readTemplate('components/layout/cms-search.tsx') },\n 'cms-sign-out': { relPath: 'components/layout/cms-sign-out.tsx', content: () => readTemplate('components/layout/cms-sign-out.tsx') },\n // Shared\n 'page-header': { relPath: 'components/shared/page-header.tsx', content: () => readTemplate('components/shared/page-header.tsx') },\n 'delete-dialog': { relPath: 'components/shared/delete-dialog.tsx', content: () => readTemplate('components/shared/delete-dialog.tsx') },\n 'status-badge': { relPath: 'components/shared/status-badge.tsx', content: () => readTemplate('components/shared/status-badge.tsx') },\n // Data table\n 'data-table': { relPath: 'components/data-table/data-table.tsx', content: () => readTemplate('components/data-table/data-table.tsx') },\n 'data-table-pagination': { relPath: 'components/data-table/data-table-pagination.tsx', content: () => readTemplate('components/data-table/data-table-pagination.tsx') },\n 'data-table-toolbar': { relPath: 'components/data-table/data-table-toolbar.tsx', content: () => readTemplate('components/data-table/data-table-toolbar.tsx') },\n // Hooks\n 'use-upload': { relPath: 'hooks/use-upload.ts', content: () => readTemplate('hooks/use-upload.ts') },\n 'use-editor-image-upload': { relPath: 'hooks/use-editor-image-upload.ts', content: () => readTemplate('hooks/use-editor-image-upload.ts') },\n 'use-local-storage': { relPath: 'hooks/use-local-storage.ts', content: () => readTemplate('hooks/use-local-storage.ts') },\n 'use-cms-theme': { relPath: 'hooks/use-cms-theme.tsx', content: () => readTemplate('hooks/use-cms-theme.tsx') },\n 'use-users': { relPath: 'hooks/use-users.ts', content: () => readTemplate('hooks/use-users.ts') },\n 'use-mobile': { relPath: 'hooks/use-mobile.ts', content: () => readTemplate('hooks/use-mobile.ts') },\n // Types\n 'types-index': { relPath: 'types/index.ts', content: () => readTemplate('types/index.ts') },\n 'auth-types': { relPath: 'types/auth.ts', content: () => readTemplate('types/auth.ts') },\n 'table-meta': { relPath: 'types/table-meta.ts', content: () => readTemplate('types/table-meta.ts') },\n // Utils\n cn: { relPath: 'utils/cn.ts', content: () => readTemplate('utils/cn.ts') },\n seo: { relPath: 'utils/seo.ts', content: () => readTemplate('utils/seo.ts') },\n validation: { relPath: 'utils/validation.ts', content: () => readTemplate('utils/validation.ts') },\n webhook: { relPath: 'utils/webhook.ts', content: () => readTemplate('utils/webhook.ts') },\n mailchimp: { relPath: 'utils/mailchimp.ts', content: () => readTemplate('utils/mailchimp.ts') },\n // Auth\n 'auth-middleware': { relPath: 'lib/auth/middleware.ts', content: () => readTemplate('lib/auth/middleware.ts') },\n 'auth-layout': { relPath: 'app/(cms)/cms/(authenticated)/layout.tsx', content: () => readTemplate('pages/authenticated-layout.tsx'), base: 'cwd' },\n 'account-layout': { relPath: 'app/(cms)/cms/(account)/layout.tsx', content: () => readTemplate('pages/account-layout.tsx'), base: 'cwd' },\n 'profile-page': { relPath: 'app/(cms)/cms/(account)/profile/page.tsx', content: () => readTemplate('pages/profile/profile-page.tsx'), base: 'cwd' },\n 'profile-form': { relPath: 'app/(cms)/cms/(account)/profile/profile-form.tsx', content: () => readTemplate('pages/profile/profile-form.tsx'), base: 'cwd' },\n // Lib\n r2: { relPath: 'lib/r2.ts', content: () => readTemplate('lib/r2.ts') },\n 'form-settings-action': { relPath: 'lib/actions/form-settings.ts', content: () => readTemplate('lib/actions/form-settings.ts') },\n 'upload-action': { relPath: 'lib/actions/upload.ts', content: () => readTemplate('lib/actions/upload.ts') },\n 'users-action': { relPath: 'lib/actions/users.ts', content: () => readTemplate('lib/actions/users.ts') },\n 'profile-action': { relPath: 'lib/actions/profile.ts', content: () => readTemplate('lib/actions/profile.ts') },\n // Markdown\n 'markdown-render': { relPath: 'lib/markdown/render.ts', content: () => readTemplate('lib/markdown/render.ts') },\n 'markdown-format': { relPath: 'lib/markdown/format.ts', content: () => readTemplate('lib/markdown/format.ts') },\n 'markdown-cached': { relPath: 'lib/markdown/cached.ts', content: () => readTemplate('lib/markdown/cached.ts') },\n}\n\n/**\n * Get all available static UI component names from templates/ui/\n */\nfunction getStaticUiComponents(): string[] {\n const cliRoot = findCliRoot()\n const uiDir = path.join(cliRoot, 'templates', 'ui')\n if (!fs.existsSync(uiDir)) return []\n return fs\n .readdirSync(uiDir)\n .filter((f: string) => f.endsWith('.tsx') || f.endsWith('.ts'))\n .map((f: string) => f.replace(/\\.(tsx|ts)$/, ''))\n}\n\nfunction getAllComponentNames(): string[] {\n const staticUi = getStaticUiComponents()\n const templateKeys = Object.keys(TEMPLATE_REGISTRY)\n return [...new Set([...staticUi, ...templateKeys, 'tiptap'])].sort()\n}\n\nexport const updateComponentCommand = new Command('update')\n .alias('update-component')\n .description('Update CMS components from the latest CLI templates')\n .argument('[components...]', 'Component names to update (e.g., media-upload-field button)')\n .option('--list', 'List all available components')\n .option('--all', 'Update all components')\n .option('--cwd <path>', 'Project root path')\n .action(async (components: string[], options: { list?: boolean; all?: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n if (options.list) {\n const all = getAllComponentNames()\n clack.intro('Available components')\n\n const uiComponents = getStaticUiComponents()\n const templateKeys = Object.keys(TEMPLATE_REGISTRY).sort()\n\n // UI components table\n console.log()\n console.log(` UI Components (${uiComponents.length})`)\n console.log(` ${'─'.repeat(50)}`)\n console.log(` ${'Name'.padEnd(28)} ${'Path'}`)\n console.log(` ${'─'.repeat(50)}`)\n for (const name of uiComponents) {\n console.log(` ${name.padEnd(28)} components/ui/${name}.tsx`)\n }\n\n // Template components table\n console.log()\n console.log(` Template Components (${templateKeys.length})`)\n console.log(` ${'─'.repeat(56)}`)\n console.log(` ${'Name'.padEnd(28)} ${'Path'}`)\n console.log(` ${'─'.repeat(56)}`)\n for (const name of templateKeys) {\n console.log(` ${name.padEnd(28)} ${TEMPLATE_REGISTRY[name].relPath}`)\n }\n\n // Special\n console.log()\n console.log(` Special`)\n console.log(` ${'─'.repeat(56)}`)\n console.log(` ${'tiptap'.padEnd(28)} components/ui/tiptap/ (all files)`)\n console.log()\n\n clack.outro(`${all.length} components available`)\n return\n }\n\n if (!options.all && components.length === 0) {\n clack.log.error('Provide component names or use --all. Run with --list to see available components.')\n process.exit(1)\n }\n\n const config = await resolveConfig(cwd)\n const cms = path.resolve(cwd, config.paths.cms)\n\n if (!fs.existsSync(cms)) {\n clack.cancel(`CMS directory not found at ${config.paths.cms}. Run 'betterstart init' first.`)\n process.exit(1)\n }\n\n clack.intro('BetterStart Update Components')\n\n const toUpdate = options.all ? getAllComponentNames() : components\n const cliRoot = findCliRoot()\n const uiDir = path.join(cliRoot, 'templates', 'ui')\n let updated = 0\n let skipped = 0\n\n for (const name of toUpdate) {\n // 1. Check template registry (template functions)\n if (TEMPLATE_REGISTRY[name]) {\n const entry = TEMPLATE_REGISTRY[name]\n const baseDir = entry.base === 'cwd' ? cwd : cms\n const destPath = path.join(baseDir, entry.relPath)\n fsExtra.ensureDirSync(path.dirname(destPath))\n fs.writeFileSync(destPath, entry.content(), 'utf-8')\n clack.log.success(`Updated ${entry.relPath}`)\n updated++\n continue\n }\n\n // 2. Check static UI templates\n const uiFile = fs.readdirSync(uiDir).find(\n (f: string) => f.replace(/\\.(tsx|ts)$/, '') === name,\n )\n if (uiFile) {\n const destPath = path.join(cms, 'components', 'ui', uiFile)\n fsExtra.ensureDirSync(path.dirname(destPath))\n fs.copyFileSync(path.join(uiDir, uiFile), destPath)\n clack.log.success(`Updated components/ui/${uiFile}`)\n updated++\n continue\n }\n\n // 3. Special: tiptap directory\n if (name === 'tiptap') {\n const srcDir = path.join(cliRoot, 'templates', 'tiptap')\n const destDir = path.join(cms, 'components', 'ui', 'tiptap')\n if (fs.existsSync(srcDir)) {\n fsExtra.copySync(srcDir, destDir, { overwrite: true })\n clack.log.success('Updated components/ui/tiptap/ (all files)')\n updated++\n } else {\n clack.log.warning('tiptap templates not found')\n skipped++\n }\n continue\n }\n\n clack.log.warning(`Unknown component: ${name}`)\n skipped++\n }\n\n clack.outro(`Updated ${updated} component${updated !== 1 ? 's' : ''}${skipped > 0 ? `, ${skipped} skipped` : ''}`)\n })\n","/**\n * update-deps command — (re-)install all required CMS dependencies.\n * Safe to run repeatedly; the package manager will skip already-installed packages.\n */\n\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport { installDependenciesAsync } from '../init/scaffolders/dependencies.js'\nimport { detectPackageManager } from '../utils/package-manager.js'\n\nexport const updateDepsCommand = new Command('update-deps')\n .description('Install or update all CMS dependencies')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Update Dependencies')\n\n const pm = detectPackageManager(cwd)\n clack.log.info(`Package manager: ${pm}`)\n\n const config = await resolveConfig(cwd)\n const includeEmail = config.features?.email ?? true\n\n const s = clack.spinner()\n s.start('Installing dependencies...')\n\n const result = await installDependenciesAsync({\n cwd,\n pm,\n includeEmail,\n includeBiome: false\n })\n\n if (result.success) {\n s.stop(`Installed ${result.coreDeps.length} deps + ${result.devDeps.length} dev deps`)\n } else {\n s.stop('Dependency install failed')\n clack.log.error(result.error ?? 'Unknown error')\n process.exit(1)\n }\n\n clack.outro('Dependencies updated')\n })\n","/**\n * update-styles command — replace cms-globals.css with the latest version\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport { readTemplate } from '../init/templates/reader.js'\n\nexport const updateStylesCommand = new Command('update-styles')\n .description('Replace cms-globals.css with the latest version from the CLI')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Update Styles')\n\n const config = await resolveConfig(cwd)\n const cmsDir = config.paths?.cms ?? './cms'\n const targetPath = path.join(cwd, cmsDir, 'cms-globals.css')\n\n if (!fs.existsSync(targetPath)) {\n clack.cancel(`cms-globals.css not found at ${path.relative(cwd, targetPath)}`)\n process.exit(1)\n }\n\n fs.writeFileSync(targetPath, readTemplate('cms-globals.css'), 'utf-8')\n\n clack.log.success(`Updated ${path.relative(cwd, targetPath)}`)\n clack.outro('Styles updated')\n })\n"],"mappings":"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","names":["Command","path","fs","path","path","fs","content","parsed","fs","path","p","path","fs","fs","path","path","fs","p","fs","path","path","fs","fs","path","path","fs","fs","path","fs","path","fs","path","path","fs","p","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fns","fs","path","generateColumnDef","fs","path","path","fs","generateColumns","path","fs","generateColumnDef","fs","path","path","fs","fs","path","findTableEnd","path","fs","fs","path","path","fs","fs","path","base","generateFieldJSX","buildZodFields","buildDefaultValues","path","fs","buildZodFields","buildDefaultValues","generateFieldJSX","fs","path","group","generateFieldJSX","buildZodFields","buildDefaultValues","path","fs","fs","path","path","fs","fs","path","parseNavigationFile","extractTopLevelArray","parseItemsBlock","parseSingleItem","generateNavigationCode","appendItem","fs","path","generatePage","path","fs","fs","path","generatePageContent","path","fs","fs","path","path","fs","fs","path","generateTable","path","fs","generateColumns","generateTable","generatePageContent","generatePage","execFileSync","fs","path","fs","path","path","fs","execFileSync","path","result","execFileSync","spawn","fs","path","p","Command","pc","execFileSync","p","p","path","fs","path","path","path","path","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","path","path","fs","path","path","path","fs","path","path","fs","fs","path","fs","path","fs","path","Command","Command","path","password","fs","runSeed","spinner","Command","pc","path","fs","execFileSync","readTemplate","spawn","password","fs","path","Command","findTableEnd","fs","Command","path","execFileSync","fs","path","p","Command","pc","Command","path","pc","execFileSync","fs","fs","path","p","Command","pc","fs","stripJsonComments","findMainCss","path","fs","p","Command","pc","fs","path","clack","Command","path","fs","Command","path","clack","Command","Command","path","fs","path","clack","Command","Command","path","fs","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/generate.ts","../src/config/resolver.ts","../src/core/schema-reader.ts","../src/core/field-helpers/walking.ts","../src/core/field-helpers/flattening.ts","../src/core/field-helpers/form-fields.ts","../src/generators/email-template.ts","../src/utils/string.ts","../src/generators/form-admin/orchestrator.ts","../src/generators/form-admin/admin-columns.ts","../src/generators/form-admin/admin-page.ts","../src/generators/form-admin/admin-page-content.ts","../src/generators/form-admin/admin-settings-page.ts","../src/generators/form-admin/admin-table.ts","../src/generators/form-admin/admin-view-page.ts","../src/generators/form-navigation.ts","../src/generators/form-pipeline/form-actions.ts","../src/generators/form-pipeline/form-component-multistep.ts","../src/generators/form-pipeline/form-component-shared.ts","../src/core/type-mappers/drizzle.ts","../src/core/type-mappers/zod.ts","../src/core/type-mappers/typescript.ts","../src/generators/form-pipeline/form-component-single.ts","../src/generators/form-pipeline/form-component.ts","../src/generators/form-pipeline/form-database.ts","../src/generators/form-pipeline/form-hook.ts","../src/generators/form-pipeline/pipeline.ts","../src/generators/actions/entity-actions.ts","../src/core/constants.ts","../src/generators/actions/action-helpers.ts","../src/generators/actions/entity-file-contents.ts","../src/generators/actions/single-actions.ts","../src/generators/cache.ts","../src/generators/columns/generate-columns.ts","../src/generators/columns/column-defs.ts","../src/generators/columns/column-actions.ts","../src/generators/columns/custom-cell.ts","../src/generators/create-page.ts","../src/generators/database.ts","../src/generators/edit-page.ts","../src/generators/form/form-entity.ts","../src/generators/form/zod-schema.ts","../src/generators/form/field-jsx-nested.ts","../src/generators/form/field-jsx.ts","../src/generators/form/form-shared.ts","../src/generators/form/form-single.ts","../src/generators/hook.ts","../src/generators/navigation.ts","../src/generators/page.ts","../src/generators/page-content.ts","../src/generators/single-page.ts","../src/generators/table.ts","../src/generators/index.ts","../src/generators/post-generate.ts","../src/utils/package-manager.ts","../src/commands/init.ts","../src/init/prompts/database.ts","../src/init/prompts/features.ts","../src/init/prompts/project.ts","../src/init/scaffolders/api-routes.ts","../src/utils/fs.ts","../src/init/scaffolders/auth.ts","../src/init/scaffolders/base.ts","../src/init/scaffolders/biome.ts","../src/init/scaffolders/components.ts","../src/utils/detect.ts","../src/init/templates/data/cms.ts","../src/init/scaffolders/database.ts","../src/init/scaffolders/dependencies.ts","../src/init/scaffolders/env.ts","../src/utils/env.ts","../src/init/scaffolders/layout.ts","../src/init/scaffolders/preset.ts","../src/init/templates/presets/blog-categories.ts","../src/init/templates/presets/blog-posts.ts","../src/init/templates/presets/default-settings.ts","../src/init/templates/presets/full-contact.ts","../src/init/templates/presets/full-navigation.ts","../src/init/scaffolders/tailwind.ts","../src/init/scaffolders/tsconfig.ts","../src/commands/seed.ts","../src/commands/remove.ts","../src/commands/setup-r2.ts","../src/commands/uninstall.ts","../src/commands/uninstall-cleaners.ts","../src/commands/update-component.ts","../src/commands/update-deps.ts","../src/commands/update-styles.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { generateCommand } from './commands/generate.js'\nimport { initCommand } from './commands/init.js'\nimport { removeCommand } from './commands/remove.js'\nimport { seedCommand } from './commands/seed.js'\nimport { setupR2Command } from './commands/setup-r2.js'\nimport { uninstallCommand } from './commands/uninstall.js'\nimport { updateComponentCommand } from './commands/update-component.js'\nimport { updateDepsCommand } from './commands/update-deps.js'\nimport { updateStylesCommand } from './commands/update-styles.js'\n\nconst program = new Command()\n\nprogram\n .name('betterstart')\n .description('Scaffold a full-featured CMS into any Next.js 16 application')\n .version('0.1.0')\n\nprogram.addCommand(initCommand)\nprogram.addCommand(generateCommand)\nprogram.addCommand(removeCommand)\nprogram.addCommand(seedCommand)\nprogram.addCommand(setupR2Command)\nprogram.addCommand(uninstallCommand)\nprogram.addCommand(updateComponentCommand)\nprogram.addCommand(updateDepsCommand)\nprogram.addCommand(updateStylesCommand)\n\nprogram.parse()\n","/**\n * generate command — read schema, detect type, run pipeline\n */\n\nimport path from 'node:path'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport type { LoadedSchema } from '../core/schema-reader.js'\nimport { listEntitySchemas, listFormSchemas, loadSchema, SchemaNotFoundError, validateLoadedSchema } from '../core/schema-reader.js'\nimport { runFormPipeline } from '../generators/form-pipeline/index.js'\nimport { runEntityPipeline, runSinglePipeline } from '../generators/index.js'\nimport { runPostGenerate } from '../generators/post-generate.js'\n\nexport const generateCommand = new Command('generate')\n .alias('g')\n .description('Generate entity or form from a JSON schema')\n .argument('[schema]', 'Schema name (e.g. posts, categories, contact)')\n .option('-f, --force', 'Overwrite existing generated files', false)\n .option('-a, --all', 'Regenerate all schemas', false)\n .option('--skip-migration', 'Skip running db:push after generation', false)\n .option('--cwd <path>', 'Project root path')\n .action(\n async (\n schemaName: string | undefined,\n options: { force: boolean; all: boolean; skipMigration: boolean; cwd?: string }\n ) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n if (options.all) {\n await generateAll(cwd, options)\n return\n }\n\n if (!schemaName) {\n console.error(' Error: schema name is required (or use --all)')\n process.exit(1)\n }\n\n console.log('\\n BetterStart Generator\\n')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n console.log(` Project root: ${cwd}`)\n console.log(` Loading schema: ${schemaName}.json\\n`)\n\n // Load schema\n let loaded: LoadedSchema\n try {\n loaded = loadSchema(schemasDir, schemaName)\n } catch (err) {\n if (err instanceof SchemaNotFoundError) {\n console.error(` ${err.message}`)\n console.error(\n `\\n Create a schema file at: ${path.join(schemasDir, `${schemaName}.json`)}`\n )\n } else {\n console.error(\n ` Error loading schema: ${err instanceof Error ? err.message : String(err)}`\n )\n }\n process.exit(1)\n }\n\n // Validate schema\n const validationErrors = validateLoadedSchema(loaded)\n if (validationErrors.length > 0) {\n console.error(' Schema validation failed:\\n')\n for (const error of validationErrors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n console.log(` Schema validated (type: ${loaded.type})\\n`)\n\n // Route to correct pipeline\n if (loaded.type === 'form') {\n console.log(' Generating form files...\\n')\n\n const result = runFormPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Form generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n console.log('\\n Form generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n return\n }\n\n // Single pipeline\n if (loaded.type === 'single') {\n console.log(' Generating single schema files...\\n')\n\n const result = runSinglePipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Single generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n console.log('\\n Single generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n return\n }\n\n // Entity pipeline\n console.log(' Generating files...\\n')\n\n const result = runEntityPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: options.skipMigration\n })\n\n if (!result.success) {\n console.error('\\n Generation completed with errors:\\n')\n for (const error of result.errors) {\n console.error(` - ${error}`)\n }\n process.exit(1)\n }\n\n // Summary\n console.log('\\n Generation complete!\\n')\n console.log(` ${result.files.length} files generated:`)\n for (const file of result.files) {\n console.log(` - ${file}`)\n }\n\n // Post-generation: db:push + lint:fix\n runPostGenerate(cwd, schemaName, {\n skipMigration: options.skipMigration\n })\n console.log('')\n }\n )\n\n// ============================================================================\n// --all: regenerate every schema\n// ============================================================================\n\nasync function generateAll(\n cwd: string,\n options: { force: boolean; skipMigration: boolean }\n) {\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n const entityNames = listEntitySchemas(schemasDir)\n const formNames = listFormSchemas(schemasDir)\n const allNames = [...entityNames, ...formNames]\n\n if (allNames.length === 0) {\n console.error(`\\n No schemas found in ${schemasDir}\\n`)\n process.exit(1)\n }\n\n console.log(`\\n BetterStart Generator — regenerating ${allNames.length} schema(s)\\n`)\n\n let totalFiles = 0\n const failed: string[] = []\n\n for (const name of allNames) {\n try {\n const loaded = loadSchema(schemasDir, name)\n const validationErrors = validateLoadedSchema(loaded)\n if (validationErrors.length > 0) {\n console.error(` ✗ ${name} — validation failed`)\n failed.push(name)\n continue\n }\n\n let files: string[] = []\n\n if (loaded.type === 'form') {\n const result = runFormPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n } else if (loaded.type === 'single') {\n const result = runSinglePipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n } else {\n const result = runEntityPipeline(loaded.schema, cwd, config, {\n force: options.force,\n skipMigration: true\n })\n files = result.files\n if (!result.success) {\n failed.push(name)\n }\n }\n\n totalFiles += files.length\n console.log(` ✓ ${name} (${loaded.type}) — ${files.length} files`)\n } catch (err) {\n console.error(` ✗ ${name} — ${err instanceof Error ? err.message : String(err)}`)\n failed.push(name)\n }\n }\n\n // Run post-generate once at the end\n if (!options.skipMigration) {\n runPostGenerate(cwd, allNames[0], { skipMigration: false })\n }\n\n console.log(`\\n Done! ${totalFiles} files generated across ${allNames.length} schema(s).`)\n if (failed.length > 0) {\n console.error(` ${failed.length} failed: ${failed.join(', ')}`)\n }\n console.log('')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { BetterstartConfig } from './types.js'\n\nconst CONFIG_FILE_NAME = 'cms.config.ts'\n\nexport function getDefaultConfig(srcDir: boolean): BetterstartConfig {\n const appBase = srcDir ? './src/app' : './app'\n return {\n srcDir,\n paths: {\n cms: './cms',\n schemas: './cms/schemas',\n pages: `${appBase}/(cms)/cms/(authenticated)`,\n login: `${appBase}/(cms)/cms/login`,\n api: `${appBase}/(cms)/api/cms`\n },\n database: {\n provider: 'neon',\n migrationsDir: './cms/db/migrations'\n },\n features: {\n email: true\n },\n linter: 'biome',\n generated: {\n entities: [],\n singles: [],\n forms: []\n }\n }\n}\n\nexport function findConfigFile(cwd: string): string | undefined {\n const filePath = path.join(cwd, CONFIG_FILE_NAME)\n if (fs.existsSync(filePath)) {\n return filePath\n }\n return undefined\n}\n\nexport async function loadConfigFile(configPath: string): Promise<BetterstartConfig> {\n const { createJiti } = await import('jiti')\n\n const alias: Record<string, string> = {}\n try {\n alias['@betterstart/cli'] = fileURLToPath(import.meta.resolve('@betterstart/cli'))\n } catch {\n // Not critical — config may not import from us\n }\n\n const jiti = createJiti(import.meta.url, { alias })\n const mod = await jiti.import(configPath)\n return ((mod as Record<string, unknown>).default || mod) as BetterstartConfig\n}\n\nexport async function resolveConfig(cwd?: string): Promise<BetterstartConfig> {\n const workingDir = cwd ?? process.cwd()\n const configPath = findConfigFile(workingDir)\n\n if (!configPath) {\n const hasSrc = fs.existsSync(path.join(workingDir, 'src'))\n return getDefaultConfig(hasSrc)\n }\n\n return loadConfigFile(configPath)\n}\n","/**\n * Schema reader: load + validate JSON schemas from cms/schemas/\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, Schema } from '../types.js'\nimport { flattenFields } from './field-helpers/index.js'\n\n// ============================================================================\n// Schema Types\n// ============================================================================\n\nexport type SchemaType = 'entity' | 'single' | 'form'\n\nexport interface LoadedEntitySchema {\n type: 'entity'\n schema: Schema\n filePath: string\n}\n\nexport interface LoadedSingleSchema {\n type: 'single'\n schema: Schema\n filePath: string\n}\n\nexport interface LoadedFormSchema {\n type: 'form'\n schema: FormSchema\n filePath: string\n}\n\nexport type LoadedSchema = LoadedEntitySchema | LoadedSingleSchema | LoadedFormSchema\n\n// ============================================================================\n// Schema Loading\n// ============================================================================\n\n/**\n * Load a schema by name from the schemas directory\n * Detects entity vs form schemas automatically\n */\nexport function loadSchema(schemasDir: string, name: string): LoadedSchema {\n // Check for form schema first (in forms/ subdirectory)\n const formPath = path.join(schemasDir, 'forms', `${name}.json`)\n if (fs.existsSync(formPath)) {\n const content = fs.readFileSync(formPath, 'utf-8')\n const parsed = parseJson(content, formPath)\n return { type: 'form', schema: parsed as FormSchema, filePath: formPath }\n }\n\n // Check for entity schema\n const entityPath = path.join(schemasDir, `${name}.json`)\n if (!fs.existsSync(entityPath)) {\n throw new SchemaNotFoundError(name, schemasDir)\n }\n\n const content = fs.readFileSync(entityPath, 'utf-8')\n const parsed = parseJson(content, entityPath)\n\n const obj = parsed as Record<string, unknown>\n\n // Auto-detect form type from schema content\n if ('submitButtonText' in obj || 'steps' in obj) {\n return { type: 'form', schema: parsed as FormSchema, filePath: entityPath }\n }\n\n // Detect single schema via explicit type field\n if (obj.type === 'single') {\n return { type: 'single', schema: parsed as Schema, filePath: entityPath }\n }\n\n return { type: 'entity', schema: parsed as Schema, filePath: entityPath }\n}\n\n/**\n * List all available entity schemas in the schemas directory\n */\nexport function listEntitySchemas(schemasDir: string): string[] {\n if (!fs.existsSync(schemasDir)) return []\n return fs\n .readdirSync(schemasDir)\n .filter((f) => f.endsWith('.json') && f !== 'schema.json')\n .map((f) => f.replace('.json', ''))\n}\n\n/**\n * List all available form schemas\n */\nexport function listFormSchemas(schemasDir: string): string[] {\n const formsDir = path.join(schemasDir, 'forms')\n if (!fs.existsSync(formsDir)) return []\n return fs\n .readdirSync(formsDir)\n .filter((f) => f.endsWith('.json'))\n .map((f) => f.replace('.json', ''))\n}\n\n// ============================================================================\n// Schema Validation\n// ============================================================================\n\n/**\n * Validate an entity schema structure\n * Returns an array of error messages (empty = valid)\n */\nexport function validateEntitySchema(schema: Schema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\n if (!Array.isArray(schema.columns) || schema.columns.length === 0) {\n errors.push('Schema must have at least one column')\n }\n\n // Validate fields\n for (const field of schema.fields || []) {\n if (field.type === 'separator') continue\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // Validate columns reference real fields\n const flatFields = flattenFields(schema.fields || [])\n const fieldNames = new Set(flatFields.map((f) => f.name))\n // Auto fields are always available\n for (const auto of [\n 'id',\n 'createdAt',\n 'updatedAt',\n 'published',\n 'submittedAt',\n 'ipAddress',\n 'userAgent'\n ]) {\n fieldNames.add(auto)\n }\n\n for (const column of schema.columns || []) {\n if (!column.accessorKey || !column.header || !column.type) {\n errors.push(`Column is missing required properties: ${JSON.stringify(column)}`)\n } else if (!fieldNames.has(column.accessorKey)) {\n errors.push(\n `Column accessorKey \"${column.accessorKey}\" does not match any field. Available: ${Array.from(fieldNames).join(', ')}`\n )\n }\n }\n\n return errors\n}\n\n/**\n * Validate a single schema structure\n * Like entity validation but skips columns requirement (no list view)\n */\nexport function validateSingleSchema(schema: Schema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\n\n // Validate fields\n for (const field of schema.fields || []) {\n if (field.type === 'separator') continue\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // No columns validation — single schemas have no list view\n\n return errors\n}\n\n/**\n * Validate a form schema structure\n */\nexport function validateFormSchema(schema: FormSchema): string[] {\n const errors: string[] = []\n\n if (!schema.name || typeof schema.name !== 'string') {\n errors.push('Form schema must have a valid \"name\" field')\n }\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Form schema must have a valid \"label\" field')\n }\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Form schema must have a valid \"description\" field')\n }\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Form schema must have a valid \"icon\" field')\n }\n\n const hasFields = Array.isArray(schema.fields) && schema.fields.length > 0\n const hasSteps = Array.isArray(schema.steps) && schema.steps.length > 0\n\n if (!hasFields && !hasSteps) {\n errors.push('Form schema must have either \"fields\" or \"steps\"')\n }\n if (hasFields && hasSteps) {\n errors.push('Form schema cannot have both \"fields\" and \"steps\"')\n }\n\n if (hasSteps) {\n for (const step of schema.steps!) {\n if (!step.name || !step.label) {\n errors.push(`Form step is missing name or label: ${JSON.stringify(step)}`)\n }\n if (!Array.isArray(step.fields) || step.fields.length === 0) {\n errors.push(`Form step \"${step.name}\" must have at least one field`)\n }\n }\n }\n\n return errors\n}\n\n/**\n * Validate a loaded schema (auto-detects type)\n */\nexport function validateLoadedSchema(loaded: LoadedSchema): string[] {\n if (loaded.type === 'entity') {\n return validateEntitySchema(loaded.schema)\n }\n if (loaded.type === 'single') {\n return validateSingleSchema(loaded.schema)\n }\n return validateFormSchema(loaded.schema)\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nexport class SchemaNotFoundError extends Error {\n constructor(name: string, schemasDir: string) {\n super(\n `Schema \"${name}\" not found. Looked in:\\n - ${path.join(schemasDir, `${name}.json`)}\\n - ${path.join(schemasDir, 'forms', `${name}.json`)}`\n )\n this.name = 'SchemaNotFoundError'\n }\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nfunction parseJson(content: string, filePath: string): unknown {\n try {\n return JSON.parse(content)\n } catch {\n throw new Error(`Failed to parse JSON schema: ${filePath}`)\n }\n}\n","/**\n * Field tree walking and type checking utilities\n */\n\nimport type { SchemaField } from '../../types.js'\n\n// ============================================================================\n// Field Tree Walking\n// ============================================================================\n\nexport interface WalkFieldsOptions {\n includeLists?: boolean\n includeGroups?: boolean\n includeTabs?: boolean\n}\n\nconst DEFAULT_WALK_OPTIONS: WalkFieldsOptions = {\n includeLists: true,\n includeGroups: true,\n includeTabs: true\n}\n\n/**\n * Walk through all fields in a schema, including nested ones\n */\nexport function walkFields(\n fields: SchemaField[],\n callback: (field: SchemaField, depth: number, parent?: SchemaField) => void,\n options: WalkFieldsOptions = DEFAULT_WALK_OPTIONS\n): void {\n function walk(fieldsToWalk: SchemaField[], depth: number, parent?: SchemaField): void {\n for (const field of fieldsToWalk) {\n callback(field, depth, parent)\n\n if (options.includeGroups && (field.type === 'group' || field.type === 'section') && field.fields) {\n walk(field.fields, depth + 1, field)\n }\n if (options.includeLists && field.type === 'list' && field.fields) {\n walk(field.fields, depth + 1, field)\n }\n if (options.includeTabs && field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n walk(tab.fields, depth + 1, field)\n }\n }\n }\n }\n }\n\n walk(fields, 0)\n}\n\n// ============================================================================\n// Field Type Checking\n// ============================================================================\n\n/**\n * Check if any field in the tree matches a specific type\n */\nexport function hasFieldType(\n fields: SchemaField[],\n type: string,\n options?: WalkFieldsOptions\n): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (field.type === type) found = true\n },\n options\n )\n return found\n}\n\n/**\n * Check if any field in the tree matches any of the given types\n */\nexport function hasAnyFieldType(\n fields: SchemaField[],\n types: string[],\n options?: WalkFieldsOptions\n): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (types.includes(field.type)) found = true\n },\n options\n )\n return found\n}\n\n/**\n * Check if any field uses icons (either icon type or hasIcon property)\n */\nexport function hasIconUsage(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n let found = false\n walkFields(\n fields,\n (field) => {\n if (field.type === 'icon' || field.hasIcon) found = true\n },\n options\n )\n return found\n}\n\nexport function hasRelationshipField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'relationship', options)\n}\n\nexport function hasMarkdownField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'markdown', options)\n}\n\nexport function hasTextareaField(fields: SchemaField[], options?: WalkFieldsOptions): boolean {\n return hasFieldType(fields, 'text', options)\n}\n\n/**\n * Collect all fields of a specific type\n */\nexport function collectFieldsByType(\n fields: SchemaField[],\n type: string,\n options?: WalkFieldsOptions\n): SchemaField[] {\n const result: SchemaField[] = []\n walkFields(\n fields,\n (field) => {\n if (field.type === type) result.push(field)\n },\n options\n )\n return result\n}\n","/**\n * Field flattening and collection utilities\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { collectFieldsByType } from './walking.js'\n\n// ============================================================================\n// Field Flattening\n// ============================================================================\n\nconst AUTO_ID_FIELD: SchemaField = {\n name: 'id',\n type: 'serial',\n primaryKey: true\n}\n\n/**\n * Ensure fields have an ID field - automatically injects one if not present\n */\nexport function ensureIdField(fields: SchemaField[]): SchemaField[] {\n const hasId = fields.some((f) => f.primaryKey || f.name === 'id')\n return hasId ? fields : [AUTO_ID_FIELD, ...fields]\n}\n\n/**\n * Flatten group and tabs fields into individual fields for database operations\n * Automatically ensures an ID field exists\n */\nexport function flattenFields(fields: SchemaField[]): SchemaField[] {\n return flattenFieldsWithoutIdCheck(ensureIdField(fields))\n}\n\nfunction flattenFieldsWithoutIdCheck(fields: SchemaField[]): SchemaField[] {\n const flattened: SchemaField[] = []\n\n for (const field of fields) {\n if ((field.type === 'group' || field.type === 'section') && field.fields) {\n flattened.push(...flattenFieldsWithoutIdCheck(field.fields))\n } else if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n flattened.push(...flattenFieldsWithoutIdCheck(tab.fields))\n }\n }\n } else {\n flattened.push(field)\n }\n }\n\n return flattened\n}\n\n// ============================================================================\n// Field Collection\n// ============================================================================\n\n/**\n * Get all many-to-many relationship fields\n */\nexport function getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n const flat = flattenFields(fields)\n return flat.filter((f) => f.type === 'relationship' && f.multiple === true && f.relationship)\n}\n\n/**\n * Get all single relationship fields (excluding many-to-many)\n */\nexport function getNestedRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship && !f.multiple) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) collect(f.fields)\n if (f.type === 'list' && f.fields) collect(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collect(tab.fields)\n }\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Collect relationship fields from top-level and groups only (not lists)\n */\nexport function collectRelationshipFieldsTopLevel(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n collect(f.fields)\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Collect ALL relationship fields including those in lists\n */\nexport function collectAllRelationshipFields(fields: SchemaField[]): SchemaField[] {\n return collectFieldsByType(fields, 'relationship')\n}\n\n/**\n * Get list fields that have nested fields (not just items)\n */\nexport function getListFieldsWithNestedFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n collect(f.fields)\n }\n }\n }\n\n collect(fields)\n return result\n}\n\n/**\n * Get nested list fields (list fields inside list fields)\n */\nexport function getNestedListFields(\n fields: SchemaField[]\n): { parent: SchemaField; nested: SchemaField }[] {\n const result: { parent: SchemaField; nested: SchemaField }[] = []\n\n const listFields = getListFieldsWithNestedFields(fields)\n for (const parent of listFields) {\n if (parent.fields) {\n for (const nested of parent.fields) {\n if (nested.type === 'list' && nested.fields && nested.fields.length > 0) {\n result.push({ parent, nested })\n }\n }\n }\n }\n\n return result\n}\n","/**\n * Form schema field helpers (for FormSchema type)\n */\n\nimport type { FormField, FormSchema, FormStep } from '../../types.js'\n\n/**\n * Get all fields from a form schema (including from steps), flattening groups\n */\nexport function getAllFormFields(schema: FormSchema): FormField[] {\n const allFields: FormField[] = []\n\n const sources = schema.steps ? schema.steps.flatMap((step) => step.fields) : schema.fields || []\n\n for (const field of sources) {\n if (field.type === 'group' && field.fields) {\n for (const nestedField of field.fields) {\n allFields.push({\n ...nestedField,\n condition: nestedField.condition || field.condition\n })\n }\n } else {\n allFields.push(field)\n }\n }\n\n return allFields\n}\n\n/**\n * Check if a form schema is multi-step\n */\nexport function isMultiStepForm(schema: FormSchema): boolean {\n return Array.isArray(schema.steps) && schema.steps.length > 0\n}\n\n/**\n * Get all concrete fields from a form schema, flattening groups and skipping dynamicFields.\n * Works with both flat schemas (schema.fields) and multi-step schemas (schema.steps).\n */\nexport function getAllFormSchemaFields(schema: FormSchema): FormField[] {\n const flatten = (fields: FormField[]): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'dynamicFields') return []\n if (field.type === 'group' && field.fields) return flatten(field.fields)\n return field.type === 'group' ? [] : [field]\n })\n }\n if (schema.fields) return flatten(schema.fields)\n if (schema.steps) return schema.steps.flatMap((step) => flatten(step.fields))\n return []\n}\n\n/**\n * Get flat array of field names for a form step (for RHF trigger validation).\n * Groups are flattened to child names, list fields use parent name,\n * hidden and dynamicFields are excluded, showWhen fields are included.\n */\nexport function getStepFieldNames(step: FormStep): string[] {\n const names: string[] = []\n const collect = (fields: FormField[]): void => {\n for (const field of fields) {\n if (field.hidden) continue\n if (field.type === 'dynamicFields') continue\n if (field.type === 'group' && field.fields) {\n collect(field.fields)\n } else if (field.name) {\n names.push(field.name)\n }\n }\n }\n collect(step.fields)\n return names\n}\n\n/**\n * Check if a form schema contains dynamicFields\n */\nexport function hasDynamicFields(schema: FormSchema): boolean {\n const check = (fields: FormField[]): boolean => {\n for (const f of fields) {\n if (f.type === 'dynamicFields') return true\n if (f.type === 'group' && f.fields && check(f.fields)) return true\n }\n return false\n }\n if (schema.fields && check(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (check(step.fields)) return true\n }\n }\n return false\n}\n","/**\n * Email template generator: creates React Email template for form submission notifications\n * Output: cms/lib/emails/<name>-submission.tsx\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { getAllFormSchemaFields, hasDynamicFields } from '../core/field-helpers/index.js'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types.js'\nimport { toPascalCase, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Type Mapping\n// ============================================================================\n\nfunction getTypeForField(field: FormField): string {\n switch (field.type) {\n case 'number':\n return 'number | null'\n case 'checkbox':\n return 'boolean | null'\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) return 'Record<string, unknown>[] | null'\n return 'string[] | null'\n default:\n return 'string | null'\n }\n}\n\n// ============================================================================\n// Field Value Rendering\n// ============================================================================\n\nfunction generateFieldValue(field: FormField): string {\n const name = field.name || ''\n\n switch (field.type) {\n case 'checkbox':\n return `{${name} ? 'Yes' : 'No'}`\n case 'upload':\n case 'file':\n return `{${name} ? (\n <Link href={${name}} style={link}>Download File</Link>\n ) : 'No file uploaded'}`\n case 'email':\n return `{${name} ? (\n <Link href={\\`mailto:\\${${name}}\\`} style={link}>{${name}}</Link>\n ) : 'N/A'}`\n case 'url':\n return `{${name} ? (\n <Link href={${name}} style={link}>{${name}}</Link>\n ) : 'N/A'}`\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) {\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? (\n ${name}.map((item, idx) => (\n <Text key={idx} style={listItem}>\n {Object.entries(item).map(([k, v]) => \\`\\${k}: \\${v}\\`).join(', ')}\n </Text>\n ))\n ) : 'N/A'}`\n }\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? ${name}.join(', ') : 'N/A'}`\n case 'date':\n return `{${name} ? new Date(${name}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : 'N/A'}`\n default:\n return `{${name} ?? 'N/A'}`\n }\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface EmailTemplateResult {\n files: string[]\n}\n\nexport function generateEmailTemplate(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): EmailTemplateResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const fields = getAllFormSchemaFields(schema).filter((f) => f.name)\n const includeDynamic = hasDynamicFields(schema)\n\n const kebab = toKebabCase(formName)\n const filePath = path.join(cwd, cmsDir, 'lib', 'emails', `${kebab}-submission.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const needsLink = fields.some(\n (f) => f.type === 'upload' || f.type === 'file' || f.type === 'email' || f.type === 'url'\n )\n const needsListItem = fields.some(\n (f) => (f.type === 'list' || f.type === 'multiselect') && f.fields && f.fields.length > 0\n )\n\n // Props interface\n const propsFields = fields.map((f) => ` ${f.name}: ${getTypeForField(f)}`).join('\\n')\n const customFieldsProp = includeDynamic ? '\\n customFields?: Record<string, unknown> | null' : ''\n\n // Field sections in email body\n const fieldSections = fields\n .map(\n (f) => ` <Row style={fieldRow}>\n <Text style={label}>${f.label}</Text>\n <Text style={value}>${generateFieldValue(f)}</Text>\n </Row>`\n )\n .join('\\n\\n')\n\n // Dynamic fields section\n const customFieldsSection = includeDynamic\n ? `\n\n {customFields && Object.keys(customFields).length > 0 && (\n <>\n <Row style={dividerRow}>\n <Text style={sectionTitle}>Additional Information</Text>\n </Row>\n {Object.entries(customFields).map(([fieldKey, fieldValue]) => (\n <Row key={fieldKey} style={fieldRow}>\n <Text style={label}>{fieldKey.replace(/([A-Z])/g, ' $1').trim()}</Text>\n <Text style={value}>{fieldValue !== null && fieldValue !== undefined ? String(fieldValue) : 'N/A'}</Text>\n </Row>\n ))}\n </>\n )}`\n : ''\n\n // Props destructuring\n const propsDestructured = [\n ...fields.map((f) => f.name),\n ...(includeDynamic ? ['customFields'] : []),\n 'submittedAt'\n ].join(',\\n ')\n\n // Optional style blocks\n const linkStyle = needsLink\n ? `\nconst link = {\n color: colors.primary,\n fontWeight: '500' as const,\n textDecoration: 'none',\n}\n`\n : ''\n\n const listItemStyle = needsListItem\n ? `\nconst listItem = {\n backgroundColor: colors.borderLight,\n borderRadius: '6px',\n color: colors.text,\n fontSize: '14px',\n lineHeight: '20px',\n marginBottom: '6px',\n padding: '8px 12px',\n}\n`\n : ''\n\n const dynamicStyles = includeDynamic\n ? `\nconst dividerRow = {\n borderTop: \\`2px solid \\${colors.border}\\`,\n marginTop: '8px',\n paddingTop: '24px',\n}\n\nconst sectionTitle = {\n color: colors.text,\n fontSize: '14px',\n fontWeight: '600' as const,\n margin: '0 0 8px',\n}\n`\n : ''\n\n const content = `import { Body, Container, Head, Heading, Html${needsLink ? ', Link' : ''}, Preview, Row, Section, Text } from '@react-email/components'\n\ninterface ${pascal}SubmissionEmailProps {\n${propsFields}${customFieldsProp}\n submittedAt: string\n}\n\nexport function ${pascal}SubmissionEmail({\n ${propsDestructured}\n}: ${pascal}SubmissionEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>New ${schema.label} Submission</Preview>\n <Body style={main}>\n <Container style={container}>\n <Section style={header}>\n <Text style={logoText}>BetterStart</Text>\n </Section>\n\n <Section style={titleSection}>\n <Heading style={h1}>New ${schema.label} Submission</Heading>\n <Text style={subtitle}>\n You received a new submission on {new Date(submittedAt).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}\n </Text>\n </Section>\n\n <Section style={card}>\n${fieldSections}${customFieldsSection}\n </Section>\n\n <Section style={footer}>\n <Text style={footerText}>\n Submitted at {new Date(submittedAt).toLocaleString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true, timeZoneName: 'short' })}\n </Text>\n <Text style={footerBrand}>BetterStart</Text>\n </Section>\n </Container>\n </Body>\n </Html>\n )\n}\n\nconst colors = {\n primary: '#7c3aed',\n background: '#f8fafc',\n cardBg: '#ffffff',\n text: '#1e293b',\n textMuted: '#64748b',\n textLight: '#94a3b8',\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n}\n\nconst main = {\n backgroundColor: colors.background,\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n padding: '40px 20px',\n}\n\nconst container = {\n margin: '0 auto',\n maxWidth: '600px',\n}\n\nconst header = {\n backgroundColor: colors.primary,\n borderRadius: '12px 12px 0 0',\n padding: '24px 32px',\n textAlign: 'center' as const,\n}\n\nconst logoText = {\n color: '#ffffff',\n fontSize: '24px',\n fontWeight: '700' as const,\n letterSpacing: '-0.02em',\n margin: '0',\n}\n\nconst titleSection = {\n backgroundColor: colors.cardBg,\n padding: '32px 32px 24px',\n textAlign: 'center' as const,\n}\n\nconst h1 = {\n color: colors.text,\n fontSize: '24px',\n fontWeight: '700' as const,\n lineHeight: '32px',\n margin: '0 0 8px',\n}\n\nconst subtitle = {\n color: colors.textMuted,\n fontSize: '14px',\n lineHeight: '20px',\n margin: '0',\n}\n\nconst card = {\n backgroundColor: colors.cardBg,\n padding: '0 32px 32px',\n}\n\nconst fieldRow = {\n borderBottom: \\`1px solid \\${colors.borderLight}\\`,\n padding: '16px 0',\n}\n\nconst label = {\n color: colors.textMuted,\n fontSize: '12px',\n fontWeight: '600' as const,\n letterSpacing: '0.025em',\n lineHeight: '16px',\n margin: '0 0 6px',\n textTransform: 'uppercase' as const,\n}\n\nconst value = {\n color: colors.text,\n fontSize: '16px',\n lineHeight: '24px',\n margin: '0',\n wordBreak: 'break-word' as const,\n}\n${linkStyle}${listItemStyle}${dynamicStyles}const footer = {\n backgroundColor: colors.cardBg,\n borderRadius: '0 0 12px 12px',\n borderTop: \\`1px solid \\${colors.border}\\`,\n padding: '24px 32px',\n textAlign: 'center' as const,\n}\n\nconst footerText = {\n color: colors.textLight,\n fontSize: '12px',\n lineHeight: '16px',\n margin: '0 0 8px',\n}\n\nconst footerBrand = {\n color: colors.textMuted,\n fontSize: '14px',\n fontWeight: '600' as const,\n margin: '0',\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Shared string helpers used across all generators.\n */\n\nexport function toPascalCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .split(/[-_\\s]+/)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\n .join('')\n}\n\nexport function toCamelCase(str: string): string {\n const p = toPascalCase(str)\n return p.charAt(0).toLowerCase() + p.slice(1)\n}\n\nexport function singularize(str: string): string {\n if (str.endsWith('ies')) return `${str.slice(0, -3)}y`\n if (str.endsWith('ves')) return `${str.slice(0, -3)}f`\n if (\n str.endsWith('sses') ||\n str.endsWith('xes') ||\n str.endsWith('ches') ||\n str.endsWith('shes') ||\n str.endsWith('zes')\n )\n return str.slice(0, -2)\n if (str.endsWith('s') && !str.endsWith('ss')) return str.slice(0, -1)\n return str\n}\n\nexport function pluralize(str: string): string {\n if (str.endsWith('s') && !str.endsWith('ss')) return str\n if (str.endsWith('y') && !['ay', 'ey', 'iy', 'oy', 'uy'].some((v) => str.endsWith(v)))\n return `${str.slice(0, -1)}ies`\n if (str.endsWith('s') || str.endsWith('x') || str.endsWith('ch') || str.endsWith('sh'))\n return `${str}es`\n return `${str}s`\n}\n\nexport function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase()\n}\n\nexport function toScreamingSnake(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toUpperCase()\n}\n\nexport function quotePropertyName(name: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name) ? name : `'${name}'`\n}\n\nexport function singularizeLabel(label: string): string {\n const words = label.split(' ')\n const lastWord = words[words.length - 1]\n words[words.length - 1] = singularize(lastWord.toLowerCase())\n words[words.length - 1] =\n words[words.length - 1].charAt(0).toUpperCase() + words[words.length - 1].slice(1)\n return words.join(' ')\n}\n","/**\n * Form admin pages generator: creates admin UI for viewing/managing form submissions\n *\n * Generates under (authenticated)/forms/<name>/:\n * page.tsx, columns.tsx, <name>-submissions-table.tsx,\n * <name>-submissions-page-content.tsx, [id]/view/page.tsx\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { getAllFormSchemaFields, hasDynamicFields } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\nimport { generateColumns } from './admin-columns.js'\nimport { generatePage } from './admin-page.js'\nimport { generatePageContent } from './admin-page-content.js'\nimport { generateSettingsPage } from './admin-settings-page.js'\nimport { generateTable } from './admin-table.js'\nimport { generateViewPage } from './admin-view-page.js'\n\n// ============================================================================\n// Result Type\n// ============================================================================\n\nexport interface FormAdminPagesResult {\n files: string[]\n}\n\n// ============================================================================\n// Generator\n// ============================================================================\n\nexport function generateFormAdminPages(\n schema: FormSchema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions\n): FormAdminPagesResult {\n const formName = schema.name\n const kebab = toKebabCase(formName)\n const pascal = toPascalCase(formName)\n const camel = toCamelCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const adminDir = path.join(cwd, pagesDir, 'forms', kebab)\n if (!fs.existsSync(adminDir)) fs.mkdirSync(adminDir, { recursive: true })\n\n const files: string[] = []\n const rel = (p: string) => path.relative(cwd, p)\n\n // 1. page.tsx\n const pagePath = path.join(adminDir, 'page.tsx')\n if (!fs.existsSync(pagePath) || options.force) {\n fs.writeFileSync(pagePath, generatePage(pascal, kebab), 'utf-8')\n }\n files.push(rel(pagePath))\n\n // 2. columns.tsx\n const columnsPath = path.join(adminDir, 'columns.tsx')\n if (!fs.existsSync(columnsPath) || options.force) {\n fs.writeFileSync(\n columnsPath,\n generateColumns(fields, pascal, kebab, camel, schema.columns),\n 'utf-8'\n )\n }\n files.push(rel(columnsPath))\n\n // 3. submissions-table.tsx\n const tablePath = path.join(adminDir, `${kebab}-submissions-table.tsx`)\n if (!fs.existsSync(tablePath) || options.force) {\n fs.writeFileSync(tablePath, generateTable(pascal, kebab, schema.label), 'utf-8')\n }\n files.push(rel(tablePath))\n\n // 4. submissions-page-content.tsx\n const contentPath = path.join(adminDir, `${kebab}-submissions-page-content.tsx`)\n if (!fs.existsSync(contentPath) || options.force) {\n fs.writeFileSync(contentPath, generatePageContent(pascal, kebab, camel, schema.label), 'utf-8')\n }\n files.push(rel(contentPath))\n\n // 5. [id]/view/page.tsx\n const viewDir = path.join(adminDir, '[id]', 'view')\n if (!fs.existsSync(viewDir)) fs.mkdirSync(viewDir, { recursive: true })\n const viewPath = path.join(viewDir, 'page.tsx')\n if (!fs.existsSync(viewPath) || options.force) {\n fs.writeFileSync(\n viewPath,\n generateViewPage(pascal, kebab, fields, schema.label, hasDynamicFields(schema)),\n 'utf-8'\n )\n }\n files.push(rel(viewPath))\n\n // 6. settings/page.tsx\n const settingsDir = path.join(adminDir, 'settings')\n if (!fs.existsSync(settingsDir)) fs.mkdirSync(settingsDir, { recursive: true })\n const settingsPath = path.join(settingsDir, 'page.tsx')\n if (!fs.existsSync(settingsPath) || options.force) {\n fs.writeFileSync(settingsPath, generateSettingsPage(pascal, kebab, schema.label), 'utf-8')\n }\n files.push(rel(settingsPath))\n\n return { files }\n}\n","import type { FormColumn, FormField } from '../../types.js'\n\n// ============================================================================\n// Column Definition Helper\n// ============================================================================\n\nfunction generateColumnDef(col: FormColumn): string {\n const sortableHeader = col.sortable\n ? `header: ({ column }) => (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${col.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )`\n : `header: '${col.header}'`\n\n let cellDef: string\n switch (col.type) {\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${col.accessorKey}') as string\n return email ? <a href={\\`mailto:\\${email}\\`} className=\"text-primary hover:underline\">{email}</a> : '-'\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = row.getValue('${col.accessorKey}') as string\n return date ? new Date(date).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '-'\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as string\n return <Badge variant=\"outline\">{value || 'N/A'}</Badge>\n }`\n break\n case 'number':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as number\n return <div className=\"text-right\">{value !== null && value !== undefined ? value : '-'}</div>\n }`\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${col.accessorKey}') as string\n return <div>{value || '-'}</div>\n }`\n }\n\n return ` {\n accessorKey: '${col.accessorKey}',\n ${sortableHeader},\n ${cellDef}\n }`\n}\n\n// ============================================================================\n// Columns Generator\n// ============================================================================\n\nexport function generateColumns(\n fields: FormField[],\n pascal: string,\n kebab: string,\n camel: string,\n customColumns?: FormColumn[]\n): string {\n const hasBadge = customColumns?.some((c) => c.type === 'badge') ?? false\n\n const columnDefs = customColumns\n ? customColumns.map((col) => generateColumnDef(col)).join(',\\n')\n : fields\n .filter((f) => f.name)\n .map((f) => {\n const accessor = f.name!\n return ` {\n accessorKey: '${accessor}',\n header: ({ column }) => (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${f.label}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n ),\n cell: ({ row }) => {\n const value = row.getValue('${accessor}')\n return <div>${f.type === 'textarea' ? \"{value ? String(value).substring(0, 100) + (String(value).length > 100 ? '...' : '') : '-'}\" : \"{String(value ?? '-')}\"}</div>\n }\n }`\n })\n .join(',\\n')\n\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { delete${pascal}Submission } from '@cms/actions/${kebab}-form'\n${hasBadge ? \"import { Badge } from '@cms/components/ui/badge'\" : ''}\nimport { Button } from '@cms/components/ui/button'\nimport { Checkbox } from '@cms/components/ui/checkbox'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@cms/components/ui/alert-dialog'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ArrowUpDown, Eye, Trash } from 'lucide-react'\nimport Link from 'next/link'\nimport { useState, useTransition } from 'react'\nimport { toast } from 'sonner'\n\nfunction DeleteAction({ id }: { id: number }) {\n const [open, setOpen] = useState(false)\n const [isPending, startTransition] = useTransition()\n const queryClient = useQueryClient()\n\n const handleDelete = () => {\n startTransition(async () => {\n try {\n const result = await delete${pascal}Submission(id)\n if (result.success) {\n toast.success('Submission deleted successfully')\n queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submission')\n }\n } catch {\n toast.error('An error occurred')\n }\n })\n }\n\n return (\n <AlertDialog open={open} onOpenChange={setOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"icon\" className=\"size-8\">\n <Trash className=\"size-3\" />\n <span className=\"sr-only\">Delete</span>\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently delete this submission.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e: React.MouseEvent) => { e.preventDefault(); handleDelete() }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n\nexport const columns: ColumnDef<${pascal}SubmissionData>[] = [\n {\n id: 'select',\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')}\n onCheckedChange={(value: boolean) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value: boolean) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableHiding: false\n },\n${columnDefs},\n {\n id: 'actions',\n header: () => <div className=\"text-right\">Actions</div>,\n cell: ({ row }) => {\n const submission = row.original\n return (\n <div className=\"flex justify-end items-center gap-2\">\n <Button variant=\"outline\" size=\"icon\" className=\"size-8\" asChild>\n <Link href={\\`/cms/forms/${kebab}/\\${submission.id}/view\\`}>\n <Eye className=\"size-3\" />\n <span className=\"sr-only\">View</span>\n </Link>\n </Button>\n <DeleteAction id={submission.id} />\n </div>\n )\n }\n }\n]\n`\n}\n","export function generatePage(pascal: string, kebab: string): string {\n return `import { Suspense } from 'react'\nimport { ${pascal}SubmissionsPageContent } from './${kebab}-submissions-page-content'\nimport { columns } from './columns'\n\nexport default function Page() {\n return (\n <Suspense fallback={<div className=\"p-6\">Loading...</div>}>\n <${pascal}SubmissionsPageContent columns={columns} />\n </Suspense>\n )\n}\n`\n}\n","export function generatePageContent(pascal: string, kebab: string, camel: string, label: string): string {\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { deleteBulk${pascal}Submissions } from '@cms/actions/${kebab}-form'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n} from '@cms/components/ui/alert-dialog'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ChevronLeft, Search, Settings, Trash2 } from 'lucide-react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { parseAsString, useQueryState } from 'nuqs'\nimport { startTransition, useCallback, useState, useTransition } from 'react'\nimport { toast } from 'sonner'\nimport { ${pascal}SubmissionsTable } from './${kebab}-submissions-table'\n\ninterface ${pascal}SubmissionsPageContentProps<TValue> {\n columns: ColumnDef<${pascal}SubmissionData, TValue>[]\n}\n\nexport function ${pascal}SubmissionsPageContent<TValue>({\n columns,\n}: ${pascal}SubmissionsPageContentProps<TValue>) {\n const router = useRouter()\n const queryClient = useQueryClient()\n const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n const [selectedIds, setSelectedIds] = useState<number[]>([])\n const [deleteOpen, setDeleteOpen] = useState(false)\n const [isPending, startDeleteTransition] = useTransition()\n\n const searchAction = useCallback(\n async (formData: FormData) => {\n const value = formData.get('search') as string\n startTransition(() => {\n setSearch(value || null)\n })\n },\n [setSearch]\n )\n\n const handleBulkDelete = () => {\n startDeleteTransition(async () => {\n try {\n const result = await deleteBulk${pascal}Submissions(selectedIds)\n if (result.success) {\n toast.success(\\`\\${selectedIds.length} submission\\${selectedIds.length > 1 ? 's' : ''} deleted\\`)\n queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n setSelectedIds([])\n setDeleteOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submissions')\n }\n } catch {\n toast.error('An error occurred')\n }\n })\n }\n\n return (\n <>\n <PageHeader title=\"${label}\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} search={<form action={searchAction} className=\"flex items-center gap-2 relative\">\n <Search className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n key={search}\n name=\"search\"\n placeholder=\"Search submissions...\"\n defaultValue={search}\n className=\"w-64 pl-9 bg-white rounded-full\"\n />\n </form>} actions={<div className=\"flex items-center gap-2\">\n {selectedIds.length > 0 && (\n <AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"default\">\n <Trash2 className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Delete {selectedIds.length}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This will permanently delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? 'submission' : 'submissions'}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e: React.MouseEvent) => { e.preventDefault(); handleBulkDelete() }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n <Button variant=\"outline\" asChild>\n <Link href=\"/cms/forms/${kebab}/settings\">\n <Settings className=\"size-3.5\" />\n Settings\n </Link>\n </Button>\n </div>} />\n <main className=\"space-y-4 p-6\">\n <${pascal}SubmissionsTable\n columns={columns}\n selectedIds={selectedIds}\n setSelectedIds={setSelectedIds}\n search={search}\n />\n </main>\n </>\n )\n}\n`\n}\n","export function generateSettingsPage(pascal: string, kebab: string, label: string): string {\n return `'use client'\n\nimport {\n getFormSettings,\n testFormWebhook,\n upsertFormSettings,\n} from '@cms/actions/form-settings'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\nimport { Label } from '@cms/components/ui/label'\nimport { Switch } from '@cms/components/ui/switch'\nimport { Textarea } from '@cms/components/ui/textarea'\nimport { ChevronLeft, Loader2 } from 'lucide-react'\nimport { useRouter } from 'next/navigation'\nimport { useEffect, useState, useTransition } from 'react'\nimport { toast } from 'sonner'\n\nexport default function ${pascal}SettingsPage() {\n const router = useRouter()\n const [notificationEmails, setNotificationEmails] = useState('')\n const [webhookUrl, setWebhookUrl] = useState('')\n const [webhookEnabled, setWebhookEnabled] = useState(false)\n const [isSaving, startSaveTransition] = useTransition()\n const [isTesting, startTestTransition] = useTransition()\n const [loaded, setLoaded] = useState(false)\n\n useEffect(() => {\n getFormSettings('${kebab}').then((settings) => {\n if (settings) {\n setNotificationEmails(settings.notificationEmails ?? '')\n setWebhookUrl(settings.webhookUrl ?? '')\n setWebhookEnabled(settings.webhookEnabled)\n }\n setLoaded(true)\n })\n }, [])\n\n const handleSave = () => {\n startSaveTransition(async () => {\n const result = await upsertFormSettings('${kebab}', {\n notificationEmails: notificationEmails || null,\n webhookUrl: webhookUrl || null,\n webhookEnabled,\n })\n if (result.success) {\n toast.success('Settings saved successfully')\n } else {\n toast.error(result.error || 'Failed to save settings')\n }\n })\n }\n\n const handleTestWebhook = () => {\n startTestTransition(async () => {\n const result = await testFormWebhook('${kebab}')\n if (result.success) {\n toast.success('Test webhook sent successfully')\n } else {\n toast.error(result.error || 'Failed to send test webhook')\n }\n })\n }\n\n if (!loaded) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <Loader2 className=\"size-6 animate-spin text-muted-foreground\" />\n </div>\n )\n }\n\n return (\n <>\n <PageHeader title=\"${label} Settings\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} />\n <div className=\"space-y-6 rounded-lg border p-6 mx-6 mt-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"notificationEmails\">Notification Emails</Label>\n <Textarea\n id=\"notificationEmails\"\n placeholder=\"email@example.com, another@example.com\"\n value={notificationEmails}\n onChange={(e) => setNotificationEmails(e.target.value)}\n rows={3}\n />\n <p className=\"text-xs text-muted-foreground\">\n Comma-separated list of email addresses to notify on new submissions.\n </p>\n </div>\n\n <div className=\"space-y-4 border-t pt-6\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"webhookUrl\">Webhook URL</Label>\n <Input\n id=\"webhookUrl\"\n type=\"url\"\n placeholder=\"https://hooks.example.com/endpoint\"\n value={webhookUrl}\n onChange={(e) => setWebhookUrl(e.target.value)}\n />\n <p className=\"text-xs text-muted-foreground\">\n Receive a POST request with form data on each submission.\n </p>\n </div>\n\n <div className=\"flex items-center space-x-2\">\n <Switch\n id=\"webhookEnabled\"\n checked={webhookEnabled}\n onCheckedChange={setWebhookEnabled}\n />\n <Label htmlFor=\"webhookEnabled\">Enable Webhook</Label>\n </div>\n\n {webhookUrl && webhookEnabled && (\n <Button\n variant=\"outline\"\n onClick={handleTestWebhook}\n disabled={isTesting}\n >\n {isTesting ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Sending...\n </>\n ) : (\n 'Test Webhook'\n )}\n </Button>\n )}\n </div>\n\n <div className=\"border-t pt-6\">\n <Button onClick={handleSave} disabled={isSaving}>\n {isSaving ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Saving...\n </>\n ) : (\n 'Save Settings'\n )}\n </Button>\n </div>\n </div>\n </>\n )\n}\n`\n}\n","export function generateTable(pascal: string, kebab: string, label: string): string {\n return `'use client'\n\nimport type { ${pascal}SubmissionData } from '@cms/actions/${kebab}-form'\nimport { use${pascal}Submissions } from '@cms/hooks/use-${kebab}-form'\nimport { Button } from '@cms/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@cms/components/ui/select'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@cms/components/ui/table'\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type SortingState,\n useReactTable,\n type VisibilityState,\n} from '@tanstack/react-table'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport { useCallback, useMemo, useState } from 'react'\n\nconst PAGE_SIZE_OPTIONS = [\n { value: '10', label: '10' },\n { value: '20', label: '20' },\n { value: '50', label: '50' },\n { value: '100', label: '100' },\n { value: 'all', label: 'All' },\n]\n\ninterface ${pascal}SubmissionsTableProps<TValue> {\n columns: ColumnDef<${pascal}SubmissionData, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string\n}\n\nexport function ${pascal}SubmissionsTable<TValue>({\n columns,\n selectedIds,\n setSelectedIds,\n search,\n}: ${pascal}SubmissionsTableProps<TValue>) {\n const [sorting, setSorting] = useState<SortingState>([])\n const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n const [pageIndex, setPageIndex] = useQueryState('page', parseAsInteger.withDefault(0))\n const [pageSize, setPageSize] = useQueryState('size', parseAsInteger.withDefault(10))\n\n const effectivePageSize = pageSize === -1 ? Number.MAX_SAFE_INTEGER : pageSize\n\n const handlePageSizeChange = useCallback(\n (value: string) => {\n if (value === 'all') {\n setPageSize(-1)\n } else {\n setPageSize(Number.parseInt(value, 10))\n }\n setPageIndex(0)\n },\n [setPageSize, setPageIndex]\n )\n\n const { data, error, isPending } = use${pascal}Submissions(search)\n\n const rowSelection = useMemo(() => {\n const selection: Record<string, boolean> = {}\n const submissions = data?.submissions ?? []\n submissions.forEach((sub, idx) => {\n if (selectedIds.includes(sub.id)) {\n selection[idx.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.submissions])\n\n const handleRowSelectionChange = useCallback(\n (updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)) => {\n const submissions = data?.submissions ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n const newIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => submissions[Number.parseInt(key, 10)]?.id)\n .filter(Boolean) as number[]\n setSelectedIds(newIds)\n },\n [data?.submissions, rowSelection, setSelectedIds]\n )\n\n const table = useReactTable({\n data: data?.submissions ?? [],\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: handleRowSelectionChange,\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n pagination: { pageIndex, pageSize: effectivePageSize },\n },\n })\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded-lg border overflow-hidden\">\n <Table>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <TableHead key={header.id}>\n {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isPending ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center text-muted-foreground\">\n Loading ${label} submissions...\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center text-destructive\">\n Error: {error.message}\n </TableCell>\n </TableRow>\n ) : table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n No submissions found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <p className=\"text-sm text-muted-foreground\">Rows per page</p>\n <Select\n value={pageSize === -1 ? 'all' : pageSize.toString()}\n onValueChange={handlePageSizeChange}\n >\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent side=\"top\">\n {PAGE_SIZE_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center space-x-2\">\n <div className=\"flex w-[100px] items-center justify-center text-sm font-medium\">\n Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setPageIndex(Math.max(0, pageIndex - 1))} disabled={!table.getCanPreviousPage()}>\n Previous\n </Button>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setPageIndex(pageIndex + 1)} disabled={!table.getCanNextPage()}>\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n}\n","import type { FormField } from '../../types.js'\n\nexport function generateViewPage(\n pascal: string,\n kebab: string,\n fields: FormField[],\n label: string,\n includeDynamic: boolean\n): string {\n const fieldItems = fields\n .filter((f) => f.name)\n .map((f) => {\n const name = f.name!\n const lbl = f.label\n\n if (f.type === 'email') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">\n {submission.${name} ? (\n <a href={\\`mailto:\\${submission.${name}}\\`} className=\"text-primary hover:underline\">{submission.${name}}</a>\n ) : '-'}\n </p>\n </div>`\n }\n if (f.type === 'textarea') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm whitespace-pre-wrap\">{submission.${name} || '-'}</p>\n </div>`\n }\n if (f.type === 'checkbox') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ? 'Yes' : 'No'}</p>\n </div>`\n }\n if (f.type === 'date') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ? new Date(submission.${name}).toLocaleDateString() : '-'}</p>\n </div>`\n }\n if (f.type === 'url') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">\n {submission.${name} ? (\n <a href={submission.${name}} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-primary hover:underline break-all\">{submission.${name}}</a>\n ) : '-'}\n </p>\n </div>`\n }\n if (f.type === 'list' || f.type === 'multiselect') {\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <div className=\"text-sm\">\n {Array.isArray(submission.${name}) && submission.${name}.length > 0 ? (\n <ul className=\"list-disc list-inside space-y-1\">\n {submission.${name}.map((item: Record<string, unknown>, idx: number) => (\n <li key={idx}>{typeof item === 'string' ? item : Object.entries(item).map(([k, v]) => \\`\\${k}: \\${v}\\`).join(', ')}</li>\n ))}\n </ul>\n ) : '-'}\n </div>\n </div>`\n }\n return ` <div className=\"space-y-1\">\n <p className=\"text-sm font-medium text-muted-foreground\">${lbl}</p>\n <p className=\"text-sm\">{submission.${name} ?? '-'}</p>\n </div>`\n })\n .join('\\n')\n\n const customFieldsSection = includeDynamic\n ? `\n {submission.customFields && Object.keys(submission.customFields).length > 0 && (\n <div className=\"space-y-3 border-t pt-4\">\n <p className=\"text-sm font-semibold text-muted-foreground\">Custom Fields</p>\n {Object.entries(submission.customFields).map(([key, value]) => (\n <div key={key} className=\"space-y-1\">\n <p className=\"text-sm font-medium capitalize\">{key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <p className=\"text-sm\">{value !== null && value !== undefined ? String(value) : '-'}</p>\n </div>\n ))}\n </div>\n )}`\n : ''\n\n return `import { get${pascal}Submission } from '@cms/actions/${kebab}-form'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { connection } from 'next/server'\n\ninterface PageProps {\n params: Promise<{ id: string }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n await connection()\n const submission = await get${pascal}Submission(Number.parseInt(id, 10))\n\n if (!submission) {\n notFound()\n }\n\n return (\n <>\n <PageHeader title=\"${label} Submission\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/forms/${kebab}\"><ChevronLeft /></Link></Button>} />\n <div className=\"rounded-lg border p-6 mx-6 mt-6 space-y-4\">\n${fieldItems}${customFieldsSection}\n <div className=\"space-y-1 border-t pt-4\">\n <p className=\"text-sm font-medium text-muted-foreground\">Submitted At</p>\n <p className=\"text-sm\">\n {new Date(submission.submittedAt).toLocaleString('en-US', {\n month: 'long', day: 'numeric', year: 'numeric',\n hour: 'numeric', minute: '2-digit'\n })}\n </p>\n </div>\n </div>\n </>\n )\n}\n`\n}\n","/**\n * Form navigation generator: adds form submissions entry to cms/data/navigation.ts\n * Each form gets a flat nav item with group: 'Forms'\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { FormSchema, GeneratorOptions } from '../types.js'\nimport { toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface NavItem {\n label: string\n href: string\n icon?: string\n group?: string\n}\n\n// ============================================================================\n// Parser (mirrors entity navigation generator)\n// ============================================================================\n\nfunction parseNavigationFile(content: string): { items: NavItem[]; iconImports: string[] } {\n const iconImportMatch = content.match(/import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]lucide-react['\"]/)\n const iconImports: string[] = iconImportMatch\n ? iconImportMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s && s !== 'LucideIcon')\n : []\n\n const arrayBlock = extractTopLevelArray(content)\n if (!arrayBlock) return { items: [], iconImports }\n\n return { items: parseItemsBlock(arrayBlock), iconImports }\n}\n\nfunction extractTopLevelArray(content: string): string | null {\n const marker = content.indexOf('cmsNavigation')\n if (marker === -1) return null\n\n const eqSign = content.indexOf('=', marker)\n if (eqSign === -1) return null\n const openBracket = content.indexOf('[', eqSign)\n if (openBracket === -1) return null\n\n let depth = 0\n for (let i = openBracket; i < content.length; i++) {\n if (content[i] === '[') depth++\n if (content[i] === ']') depth--\n if (depth === 0) {\n return content.slice(openBracket + 1, i)\n }\n }\n return null\n}\n\nfunction parseItemsBlock(block: string): NavItem[] {\n const items: NavItem[] = []\n let depth = 0\n let current = ''\n let inObj = false\n\n for (const char of block) {\n if (char === '{') {\n if (depth === 0) inObj = true\n depth++\n current += char\n } else if (char === '}') {\n depth--\n current += char\n if (depth === 0 && inObj) {\n const item = parseSingleItem(current)\n if (item) items.push(item)\n current = ''\n inObj = false\n }\n } else if (inObj) {\n current += char\n }\n }\n\n return items\n}\n\nfunction parseSingleItem(str: string): NavItem | null {\n const labelMatch = str.match(/label:\\s*['\"]([^'\"]+)['\"]/)\n const hrefMatch = str.match(/href:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = str.match(/icon:\\s*(\\w+)/)\n const groupMatch = str.match(/group:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!labelMatch || !hrefMatch) return null\n\n const item: NavItem = { label: labelMatch[1], href: hrefMatch[1] }\n if (iconMatch) item.icon = iconMatch[1]\n if (groupMatch) item.group = groupMatch[1]\n\n return item\n}\n\n// ============================================================================\n// Code Generator (mirrors entity navigation generator)\n// ============================================================================\n\nfunction generateNavigationCode(items: NavItem[], iconImports: string[]): string {\n const lines: string[] = []\n\n lines.push(\"import type { LucideIcon } from 'lucide-react'\")\n lines.push(`import { ${iconImports.join(', ')} } from 'lucide-react'`)\n lines.push('')\n lines.push('export interface CmsNavigationItem {')\n lines.push(' label: string')\n lines.push(' href: string')\n lines.push(' icon?: LucideIcon')\n lines.push(' group?: string')\n lines.push('}')\n lines.push('')\n lines.push('export const cmsNavigation: CmsNavigationItem[] = [')\n\n for (let i = 0; i < items.length; i++) {\n appendItem(lines, items[i], i === items.length - 1)\n }\n\n lines.push(']')\n lines.push('')\n\n return lines.join('\\n')\n}\n\nfunction appendItem(lines: string[], item: NavItem, isLast: boolean): void {\n lines.push(' {')\n lines.push(` label: '${item.label}',`)\n\n const hasMore = item.icon != null || item.group != null\n lines.push(` href: '${item.href}'${hasMore ? ',' : ''}`)\n\n if (item.icon && item.group) {\n lines.push(` icon: ${item.icon},`)\n lines.push(` group: '${item.group}'`)\n } else if (item.icon) {\n lines.push(` icon: ${item.icon}`)\n } else if (item.group) {\n lines.push(` group: '${item.group}'`)\n }\n\n lines.push(` }${isLast ? '' : ','}`)\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface FormNavigationResult {\n files: string[]\n}\n\n/**\n * Update cms/data/navigation.ts to add form under \"Forms\" group\n */\nexport function updateFormNavigation(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): FormNavigationResult {\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n\n let items: NavItem[] = []\n let iconImports: string[] = []\n\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const parsed = parseNavigationFile(content)\n items = parsed.items\n iconImports = parsed.iconImports\n }\n\n // Create form nav item with group: 'Forms'\n const kebab = toKebabCase(schema.name)\n const formHref = `/cms/forms/${kebab}`\n const existingIndex = items.findIndex((item) => item.href === formHref)\n\n const newItem: NavItem = {\n label: schema.label,\n href: formHref,\n icon: 'Inbox',\n group: 'Forms'\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n items[existingIndex] = newItem\n } else {\n return { files: [] }\n }\n } else {\n items.push(newItem)\n }\n\n // Reorganize: Dashboard first, then ungrouped alphabetical, then grouped alphabetical\n const dashboard = items.find((item) => item.href === '/cms')\n const others = items.filter((item) => item.href !== '/cms')\n others.sort((a, b) => {\n if (!a.group && b.group) return -1\n if (a.group && !b.group) return 1\n if (a.group && b.group && a.group !== b.group) return a.group.localeCompare(b.group)\n return a.label.localeCompare(b.label)\n })\n\n items = [...(dashboard ? [dashboard] : []), ...others]\n\n // Ensure required icon is imported\n if (!iconImports.includes('Inbox')) {\n iconImports.push('Inbox')\n }\n iconImports.sort()\n\n // Write\n const dir = path.dirname(navFilePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n fs.writeFileSync(navFilePath, generateNavigationCode(items, iconImports), 'utf-8')\n\n return { files: [path.join(cmsDir, 'data', 'navigation.ts')] }\n}\n","/**\n * Form pipeline step 2: Server actions for form submissions\n * Split into individual files with barrel index.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields } from '../../core/field-helpers/index.js'\nimport type { FormField, FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\n\ninterface StepResult {\n files: string[]\n}\n\nfunction generateMailchimpCode(schema: FormSchema, fields: FormField[]): string {\n if (!schema.mailchimp) return ''\n\n let emailFieldName: string\n if (typeof schema.mailchimp === 'object' && schema.mailchimp.emailField) {\n emailFieldName = schema.mailchimp.emailField\n } else {\n const emailField = fields.find((f) => f.type === 'email')\n if (!emailField || !emailField.name) {\n console.warn(\n `Warning: Form \"${schema.name}\" has mailchimp enabled but no email field found. Skipping.`\n )\n return ''\n }\n emailFieldName = emailField.name\n }\n\n return `\\n // Add to Mailchimp audience (fire-and-forget, non-blocking)\n addToMailchimpAudience(data.${emailFieldName})`\n}\n\nexport function generateFormActions(\n schema: FormSchema,\n cwd: string,\n actionsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const tableName = `${toCamelCase(formName)}Submissions`\n const pascal = toPascalCase(formName)\n const kebab = toKebabCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, `${kebab}-form`)\n const oldFilePath = path.join(absActionsDir, `${kebab}-form.ts`)\n\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n // Build TypeScript interface fields\n const dataFields = fields\n .map((f) => {\n let tsType = 'string'\n if (f.type === 'number') tsType = 'number'\n else if (f.type === 'checkbox') tsType = 'boolean'\n else if (f.type === 'multiselect') tsType = 'string[]'\n else if (f.type === 'list') {\n tsType = f.fields && f.fields.length > 0 ? 'Record<string, unknown>[]' : 'string[]'\n }\n const isReq = f.required && !f.condition\n const opt = isReq ? '' : '?'\n const nullable = isReq ? '' : ' | null'\n return ` ${f.name}${opt}: ${tsType}${nullable}`\n })\n .join('\\n')\n\n const validation = fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) =>\n `if (!data.${f.name}) {\\n return { success: false, error: '${f.label} is required' }\\n }`\n )\n .join('\\n ')\n\n const mailchimpImport = schema.mailchimp\n ? `\\nimport { addToMailchimpAudience } from '@cms/utils/mailchimp'`\n : ''\n const mailchimpCall = generateMailchimpCode(schema, fields)\n\n // --- types.ts ---\n const typesContent = `export interface ${pascal}SubmissionData {\n id: number\n${dataFields}\n ipAddress: string | null\n userAgent: string | null\n submittedAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface ${pascal}SubmissionsResponse {\n submissions: ${pascal}SubmissionData[]\n total: number\n}\n\nexport interface Create${pascal}SubmissionInput {\n${dataFields}\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Create${pascal}SubmissionResult {\n success: boolean\n error?: string\n submission?: ${pascal}SubmissionData\n}\n\nexport interface Delete${pascal}SubmissionResult {\n success: boolean\n error?: string\n count?: number\n}\n`\n\n // --- get-{kebab}-submissions.ts ---\n const getSubmissionsContent = `'use server'\n\nimport { desc } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { ${pascal}SubmissionsResponse, ${pascal}SubmissionData } from './types'\n\nexport async function get${pascal}Submissions(): Promise<${pascal}SubmissionsResponse> {\n try {\n const submissions = await db.select().from(${tableName}).orderBy(desc(${tableName}.submittedAt))\n return {\n submissions: submissions as ${pascal}SubmissionData[],\n total: submissions.length\n }\n } catch (error) {\n console.error('Error fetching ${formName} submissions:', error)\n throw new Error('Failed to fetch ${formName} submissions')\n }\n}\n`\n\n // --- get-{kebab}-submission.ts ---\n const getSubmissionContent = `'use server'\n\nimport { eq } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { ${pascal}SubmissionData } from './types'\n\nexport async function get${pascal}Submission(id: number): Promise<${pascal}SubmissionData | null> {\n try {\n const [submission] = await db\n .select()\n .from(${tableName})\n .where(eq(${tableName}.id, id))\n .limit(1)\n return (submission as ${pascal}SubmissionData) ?? null\n } catch (error) {\n console.error(\\`Error fetching ${formName} submission \\${id}:\\`, error)\n throw new Error('Failed to fetch ${formName} submission')\n }\n}\n`\n\n // --- create-{kebab}-submission.ts ---\n const createContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport { getFormSettings } from '@cms/actions/form-settings'\nimport { sendWebhook } from '@cms/utils/webhook'${mailchimpImport}\nimport type { Create${pascal}SubmissionInput, Create${pascal}SubmissionResult, ${pascal}SubmissionData } from './types'\n\nexport async function create${pascal}Submission(\n data: Create${pascal}SubmissionInput\n): Promise<Create${pascal}SubmissionResult> {\n try {\n ${validation}\n\n const [submission] = await db\n .insert(${tableName})\n .values({\n ...data,\n submittedAt: new Date().toISOString()\n })\n .returning()\n\n // Resolve notification emails from form settings or env var\n const settings = await getFormSettings('${formName}')\n const notificationEmails = settings?.notificationEmails\n ? settings.notificationEmails.split(',').map((e: string) => e.trim()).filter(Boolean)\n : process.env.NOTIFICATION_EMAIL\n ? [process.env.NOTIFICATION_EMAIL]\n : []\n\n if (notificationEmails.length > 0) {\n // TODO: Send notification email using your email provider (e.g. Resend)\n console.log(\\`[${formName}] New submission — notify: \\${notificationEmails.join(', ')}\\`)\n }\n\n // Send webhook if enabled\n if (settings?.webhookEnabled && settings?.webhookUrl) {\n sendWebhook(settings.webhookUrl, {\n form_name: '${formName}',\n submission_id: submission.id,\n ...data,\n submitted_at: (submission as ${pascal}SubmissionData).submittedAt,\n })\n }${mailchimpCall}\n\n return {\n success: true,\n submission: submission as ${pascal}SubmissionData\n }\n } catch (error) {\n console.error('Error creating ${formName} submission:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to create ${formName} submission'\n }\n }\n}\n`\n\n // --- delete-{kebab}-submission.ts ---\n const deleteContent = `'use server'\n\nimport { eq } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { Delete${pascal}SubmissionResult } from './types'\n\nexport async function delete${pascal}Submission(id: number): Promise<Delete${pascal}SubmissionResult> {\n try {\n await db.delete(${tableName}).where(eq(${tableName}.id, id))\n return { success: true }\n } catch (error) {\n console.error(\\`Error deleting ${formName} submission \\${id}:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${formName} submission'\n }\n }\n}\n`\n\n // --- delete-bulk-{kebab}-submissions.ts ---\n const deleteBulkContent = `'use server'\n\nimport { eq, or } from 'drizzle-orm'\nimport db from '@cms/db'\nimport { ${tableName} } from '@cms/db/schema'\nimport type { Delete${pascal}SubmissionResult } from './types'\n\nexport async function deleteBulk${pascal}Submissions(ids: number[]): Promise<Delete${pascal}SubmissionResult> {\n try {\n if (ids.length === 0) return { success: true, count: 0 }\n await db.delete(${tableName}).where(\n or(...ids.map(id => eq(${tableName}.id, id)))\n )\n return { success: true, count: ids.length }\n } catch (error) {\n console.error(\\`Error bulk deleting ${formName} submissions:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to bulk delete ${formName} submissions'\n }\n }\n}\n`\n\n // --- export-{kebab}-submissions-csv.ts ---\n const exportCsvContent = `'use server'\n\nimport { get${pascal}Submissions } from './get-${kebab}-submissions'\n\nexport async function export${pascal}SubmissionsCSV(): Promise<string> {\n const { submissions } = await get${pascal}Submissions()\n if (submissions.length === 0) return ''\n const headers = Object.keys(submissions[0]).join(',')\n const rows = submissions.map((sub) =>\n Object.values(sub)\n .map((val: unknown) => {\n if (val === null || val === undefined) return ''\n const str = String(val)\n if (str.includes(',') || str.includes('\"') || str.includes('\\\\n')) {\n return \\`\"\\${str.replace(/\"/g, '\"\"')}\"\\`\n }\n return str\n })\n .join(',')\n )\n return [headers, ...rows].join('\\\\n')\n}\n`\n\n // --- export-{kebab}-submissions-json.ts ---\n const exportJsonContent = `'use server'\n\nimport { get${pascal}Submissions } from './get-${kebab}-submissions'\n\nexport async function export${pascal}SubmissionsJSON(): Promise<string> {\n const { submissions } = await get${pascal}Submissions()\n return JSON.stringify(submissions, null, 2)\n}\n`\n\n // --- index.ts (barrel) ---\n const barrelContent = `export type { ${pascal}SubmissionData, ${pascal}SubmissionsResponse, Create${pascal}SubmissionInput, Create${pascal}SubmissionResult, Delete${pascal}SubmissionResult } from './types'\nexport { get${pascal}Submissions } from './get-${kebab}-submissions'\nexport { get${pascal}Submission } from './get-${kebab}-submission'\nexport { create${pascal}Submission } from './create-${kebab}-submission'\nexport { delete${pascal}Submission } from './delete-${kebab}-submission'\nexport { deleteBulk${pascal}Submissions } from './delete-bulk-${kebab}-submissions'\nexport { export${pascal}SubmissionsCSV } from './export-${kebab}-submissions-csv'\nexport { export${pascal}SubmissionsJSON } from './export-${kebab}-submissions-json'\n`\n\n // Write all files\n const files = [\n { name: 'types.ts', content: typesContent },\n { name: `get-${kebab}-submissions.ts`, content: getSubmissionsContent },\n { name: `get-${kebab}-submission.ts`, content: getSubmissionContent },\n { name: `create-${kebab}-submission.ts`, content: createContent },\n { name: `delete-${kebab}-submission.ts`, content: deleteContent },\n { name: `delete-bulk-${kebab}-submissions.ts`, content: deleteBulkContent },\n { name: `export-${kebab}-submissions-csv.ts`, content: exportCsvContent },\n { name: `export-${kebab}-submissions-json.ts`, content: exportJsonContent },\n { name: 'index.ts', content: barrelContent }\n ]\n\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.relative(cwd, path.join(dirPath, f.name))) }\n}\n","/**\n * Multi-step wizard form component generator\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields, getStepFieldNames } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toKebabCase } from '../../utils/string.js'\nimport {\n type StepResult,\n resolveUiImport,\n escapeJsx,\n renderFieldsJSX,\n buildZodFields,\n buildDefaultValues,\n buildFieldArrayDecls,\n buildWatchDecls,\n getListFields,\n} from './form-component-shared.js'\n\nexport function generateMultiStepForm(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const kebab = toKebabCase(formName)\n const steps = schema.steps!\n\n const filePath = path.join(cwd, cmsDir, 'components', 'forms', `${kebab}-form.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n // All fields flattened (for Zod schema + defaults)\n const allFields = getAllFormSchemaFields(schema)\n const zodFields = buildZodFields(allFields)\n const defaults = buildDefaultValues(allFields)\n\n // List fields and watch declarations are global\n const listFields = getListFields(allFields)\n const hasListFields = listFields.length > 0\n const { setup: watchSetup } = buildWatchDecls(allFields)\n\n const rhfImport = hasListFields\n ? `import { useFieldArray, useForm } from 'react-hook-form'`\n : `import { useForm } from 'react-hook-form'`\n const fieldArraySetup = hasListFields ? `\\n${buildFieldArrayDecls(listFields)}\\n` : ''\n\n // Build STEPS constant\n const stepsConst = buildStepsConstant(steps, schema)\n\n // Build per-step content blocks\n const stepContentBlocks = steps\n .map((step, index) => {\n const fieldsJSX = renderFieldsJSX(step.fields)\n return ` {currentStep === ${index} && (\\n <>\\n${fieldsJSX}\\n </>\\n )}`\n })\n .join('\\n')\n\n const submitText = schema.submitButtonText || 'Submit'\n const successMessage = escapeJsx(schema.successMessage || 'Form submitted successfully!')\n\n // Resolve UI imports\n const hasRadio = allFields.some((f) => f.type === 'radio')\n const hasFileUpload = allFields.some((f) => f.type === 'file' || f.type === 'upload')\n const buttonImport = resolveUiImport(cwd, 'button')\n const formImport = resolveUiImport(cwd, 'form')\n const inputImport = resolveUiImport(cwd, 'input')\n const textareaImport = resolveUiImport(cwd, 'textarea')\n const selectImport = resolveUiImport(cwd, 'select')\n const radioGroupImport = resolveUiImport(cwd, 'radio-group')\n const mediaUploadImport = resolveUiImport(cwd, 'media-upload-field')\n\n const content = buildComponentSource({\n pascal,\n kebab,\n rhfImport,\n hasRadio,\n hasFileUpload,\n hasListFields,\n buttonImport,\n formImport,\n inputImport,\n textareaImport,\n selectImport,\n radioGroupImport,\n mediaUploadImport,\n zodFields,\n defaults,\n stepsConst,\n fieldArraySetup,\n watchSetup,\n stepContentBlocks,\n submitText,\n successMessage,\n })\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n\nfunction buildStepsConstant(\n steps: NonNullable<FormSchema['steps']>,\n schema: FormSchema\n): string {\n const entries = steps.map((step) => {\n const fieldNames = getStepFieldNames(step)\n const fieldsStr = fieldNames.map((n) => `'${n}'`).join(', ')\n const desc = step.description ? `, description: '${escapeQuotes(step.description)}'` : ''\n return ` { name: '${step.name}', label: '${escapeQuotes(step.label)}'${desc}, fields: [${fieldsStr}] }`\n })\n return `const STEPS = [\\n${entries.join(',\\n')}\\n]`\n}\n\nfunction escapeQuotes(str: string): string {\n return str.replace(/'/g, \"\\\\'\")\n}\n\ninterface ComponentParts {\n pascal: string\n kebab: string\n rhfImport: string\n hasRadio: boolean\n hasFileUpload: boolean\n hasListFields: boolean\n buttonImport: string\n formImport: string\n inputImport: string\n textareaImport: string\n selectImport: string\n radioGroupImport: string\n mediaUploadImport: string\n zodFields: string\n defaults: string\n stepsConst: string\n fieldArraySetup: string\n watchSetup: string\n stepContentBlocks: string\n submitText: string\n successMessage: string\n}\n\nfunction buildComponentSource(p: ComponentParts): string {\n const queryClientImport = p.hasFileUpload\n ? `\\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'`\n : ''\n const queryClientSetup = p.hasFileUpload\n ? `\\nconst queryClient = new QueryClient()\\n`\n : ''\n const formComponentDecl = p.hasFileUpload ? `function ${p.pascal}FormInner` : `export function ${p.pascal}Form`\n const exportWrapper = p.hasFileUpload\n ? `\\nexport function ${p.pascal}Form() {\n return (\n <QueryClientProvider client={queryClient}>\n <${p.pascal}FormInner />\n </QueryClientProvider>\n )\n}\\n`\n : ''\n\n return `'use client'\n\nimport { ChevronLeft, ChevronRight${p.hasListFields ? ', Trash2' : ''} } from 'lucide-react'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport { useState } from 'react'\n${p.rhfImport}\nimport { z } from 'zod/v3'${queryClientImport}\nimport { create${p.pascal}Submission } from '@cms/actions/${p.kebab}-form'\nimport { Button } from '${p.buttonImport}'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '${p.formImport}'\nimport { Input } from '${p.inputImport}'${p.hasFileUpload ? `\\nimport { MediaUploadField } from '${p.mediaUploadImport}'` : ''}\n${p.hasRadio ? `import { RadioGroup, RadioGroupItem } from '${p.radioGroupImport}'\\n` : ''}\nimport { Textarea } from '${p.textareaImport}'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '${p.selectImport}'\n\nconst formSchema = z.object({\n${p.zodFields}\n})\n\ntype FormValues = z.infer<typeof formSchema>\n${queryClientSetup}\n${p.stepsConst}\n\n${formComponentDecl}() {\n const [currentStep, setCurrentStep] = useQueryState('step', parseAsInteger.withDefault(0))\n const [submitted, setSubmitted] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const form = useForm<FormValues>({\n defaultValues: {\n${p.defaults}\n },\n })\n\n${p.fieldArraySetup}${p.watchSetup}\n async function handleNext() {\n const stepFields = STEPS[currentStep].fields as (keyof FormValues)[]\n const values = form.getValues()\n form.clearErrors(stepFields)\n let isValid = true\n for (const fieldName of stepFields) {\n const fieldSchema = formSchema.shape[fieldName]\n if (!fieldSchema) continue\n const result = fieldSchema.safeParse(values[fieldName])\n if (!result.success) {\n form.setError(fieldName, { type: 'validate', message: result.error.issues[0].message })\n isValid = false\n }\n }\n if (isValid) {\n setCurrentStep(currentStep + 1)\n }\n }\n\n function handleBack() {\n setCurrentStep(currentStep - 1)\n }\n\n async function onSubmit(values: FormValues) {\n const validation = formSchema.safeParse(values)\n if (!validation.success) {\n for (const issue of validation.error.issues) {\n const fieldName = issue.path[0] as keyof FormValues\n form.setError(fieldName, { type: 'validate', message: issue.message })\n }\n return\n }\n setSubmitting(true)\n try {\n const result = await create${p.pascal}Submission(validation.data)\n if (result.success) {\n setSubmitted(true)\n } else {\n form.setError('root', { message: result.error || 'Something went wrong' })\n }\n } catch {\n form.setError('root', { message: 'Something went wrong. Please try again.' })\n } finally {\n setSubmitting(false)\n }\n }\n\n if (submitted) {\n return (\n <div className=\"rounded-lg border p-6 text-center\">\n <h3 className=\"text-lg font-semibold\">Thank you!</h3>\n <p className=\"mt-2 text-muted-foreground\">${p.successMessage}</p>\n </div>\n )\n }\n\n return (\n <Form {...form}>\n <form onSubmit={(e) => e.preventDefault()} className=\"space-y-8\">\n {/* Step header */}\n <div>\n <h3 className=\"text-lg font-semibold\">{STEPS[currentStep].label}</h3>\n {'description' in STEPS[currentStep] && STEPS[currentStep].description && (\n <p className=\"text-sm text-muted-foreground mt-1\">{STEPS[currentStep].description}</p>\n )}\n </div>\n\n {/* Step content */}\n <div key={currentStep} className=\"animate-in fade-in duration-300 space-y-6\">\n${p.stepContentBlocks}\n </div>\n\n {form.formState.errors.root && (\n <p className=\"text-sm text-destructive\">{form.formState.errors.root.message}</p>\n )}\n\n {/* Navigation */}\n <div className=\"flex justify-between\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleBack}\n disabled={currentStep === 0}\n >\n <ChevronLeft className=\"mr-2 size-4\" />\n Back\n </Button>\n {currentStep < STEPS.length - 1 ? (\n <Button type=\"button\" onClick={handleNext}>\n Next\n <ChevronRight className=\"ml-2 size-4\" />\n </Button>\n ) : (\n <Button type=\"button\" disabled={submitting} onClick={() => onSubmit(form.getValues())}>\n {submitting ? 'Submitting...' : '${p.submitText}'}\n </Button>\n )}\n </div>\n </form>\n </Form>\n )\n}\n${exportWrapper}`\n}\n","/**\n * Shared helpers for form component generation\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { formFieldToZodType } from '../../core/type-mappers/index.js'\nimport type { FormField } from '../../types.js'\nimport { singularize } from '../../utils/string.js'\n\nexport interface StepResult {\n files: string[]\n}\n\n/**\n * Check if a shadcn UI component exists in the user's project.\n * Returns `@/components/ui/<name>` if found, otherwise `@cms/components/ui/<name>`.\n */\nexport function resolveUiImport(cwd: string, componentName: string): string {\n const locations = ['components/ui', 'src/components/ui']\n for (const loc of locations) {\n if (\n fs.existsSync(path.join(cwd, loc, `${componentName}.tsx`)) ||\n fs.existsSync(path.join(cwd, loc, `${componentName}.ts`))\n ) {\n return `@/components/ui/${componentName}`\n }\n }\n return `@cms/components/ui/${componentName}`\n}\n\n/** Escape text for safe use in JSX content */\nexport function escapeJsx(str: string): string {\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\n/** Flatten form fields, resolving groups and skipping dynamic fields */\nexport function flattenFormFields(fields: FormField[]): FormField[] {\n return fields.flatMap((field) => {\n if (field.type === 'dynamicFields') return []\n if (field.type === 'group' && field.fields) return flattenFormFields(field.fields)\n return field.type === 'group' ? [] : [field]\n })\n}\n\n/** Build Zod schema field entries from form fields */\nexport function buildZodFields(fields: FormField[]): string {\n return fields\n .filter((f) => f.name)\n .map((f) => ` ${f.name}: ${formFieldToZodType(f)}`)\n .join(',\\n')\n}\n\n/** Build default value entries from form fields */\nexport function buildDefaultValues(fields: FormField[]): string {\n return fields\n .filter((f) => f.name)\n .map((f) => {\n if (f.type === 'checkbox') return ` ${f.name}: false`\n if (f.type === 'number') return ` ${f.name}: undefined`\n if (f.type === 'multiselect' || f.type === 'list') return ` ${f.name}: []`\n if (f.type === 'radio' && f.defaultValue !== undefined) return ` ${f.name}: '${f.defaultValue}'`\n if (f.type === 'select' || f.type === 'radio') return ` ${f.name}: undefined`\n if (f.defaultValue !== undefined) return ` ${f.name}: '${f.defaultValue}'`\n return ` ${f.name}: ''`\n })\n .join(',\\n')\n}\n\n/** Build useFieldArray declarations for list fields */\nexport function buildFieldArrayDecls(listFields: FormField[]): string {\n return listFields\n .map(\n (f) =>\n ` const ${f.name}FieldArray = useFieldArray({ control: form.control, name: '${f.name}' })`\n )\n .join('\\n')\n}\n\n/** Build watch variable declarations for showWhen fields */\nexport function buildWatchDecls(fields: FormField[]): { setup: string; hasWatch: boolean } {\n const watchFields = new Set<string>()\n for (const f of fields) {\n if (f.showWhen) {\n watchFields.add(f.showWhen.field)\n }\n }\n if (watchFields.size === 0) return { setup: '', hasWatch: false }\n const decls = Array.from(watchFields)\n .map((wf) => ` const ${wf}Value = form.watch('${wf}')`)\n .join('\\n')\n return { setup: `\\n${decls}\\n`, hasWatch: true }\n}\n\n/** Get list fields that need useFieldArray */\nexport function getListFields(fields: FormField[]): FormField[] {\n return fields.filter(\n (f) => f.name && f.type === 'list' && f.fields && f.fields.length > 0\n )\n}\n\n/**\n * Render an array of form fields to JSX, preserving group layout.\n * Group fields render as a responsive grid wrapper; other fields render normally.\n */\nexport function renderFieldsJSX(fields: FormField[]): string {\n return fields\n .filter((f) => !f.hidden)\n .map((f) => {\n if (f.type === 'dynamicFields') return ''\n if (f.type === 'group' && f.fields) {\n const cols = f.columns || 2\n const innerJSX = renderFieldsJSX(f.fields)\n const groupJSX = ` <div className=\"grid grid-cols-1 md:grid-cols-${cols} gap-4\">\\n${innerJSX}\\n </div>`\n return f.showWhen ? wrapShowWhen(f, groupJSX) : groupJSX\n }\n if (!f.name) return ''\n return wrapShowWhen(f, generateFieldJSX(f))\n })\n .filter(Boolean)\n .join('\\n\\n')\n}\n\n/** Wrap field JSX with showWhen conditional if applicable */\nexport function wrapShowWhen(field: FormField, jsx: string): string {\n if (!field.showWhen) return jsx\n const watchVar = `${field.showWhen.field}Value`\n const { value } = field.showWhen\n if (Array.isArray(value)) {\n const vals = value.map((v) => `'${v}'`).join(', ')\n return ` {[${vals}].includes(${watchVar} as string) && (\\n${jsx}\\n )}`\n }\n return ` {${watchVar} === '${value}' && (\\n${jsx}\\n )}`\n}\n\n/** Generate JSX for a single form field */\nexport function generateFieldJSX(field: FormField): string {\n const name = field.name || ''\n const label = escapeJsx(field.label)\n const placeholder = field.placeholder || ''\n const hint = field.hint || ''\n\n const hintJSX = hint ? `\\n <FormDescription>${escapeJsx(hint)}</FormDescription>` : ''\n const hintPlainJSX = hint ? `\\n <p className=\"text-sm text-muted-foreground\">${escapeJsx(hint)}</p>` : ''\n const requiredStar = field.required ? ' <span className=\"text-destructive\">*</span>' : ''\n\n switch (field.type) {\n case 'textarea':\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <Textarea placeholder=\"${placeholder}\" {...field} />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n\n case 'radio':\n if (field.options && field.options.length > 0) {\n const radioItems = field.options\n .map(\n (opt) =>\n ` <FormLabel htmlFor=\"${name}-${opt.value}\" className=\"flex items-center space-x-2 text-sm font-medium leading-none\">\n <RadioGroupItem value=\"${opt.value}\" id=\"${name}-${opt.value}\" />\n <span>${escapeJsx(opt.label)}</span>\n </FormLabel>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem className=\"space-y-3\">\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <RadioGroup onValueChange={field.onChange} defaultValue={field.value} className=\"flex items-center space-x-2\">\n${radioItems}\n </RadioGroup>\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n\n case 'select':\n if (field.options && field.options.length > 0) {\n const optionItems = field.options\n .map(\n (opt) =>\n ` <SelectItem value=\"${opt.value}\">${escapeJsx(opt.label)}</SelectItem>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <Select onValueChange={field.onChange} defaultValue={field.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"${placeholder || 'Select...'}\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n${optionItems}\n </SelectContent>\n </Select>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n\n case 'checkbox':\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <input\n type=\"checkbox\"\n checked={field.value}\n onChange={field.onChange}\n className=\"mt-1\"\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel>${label}${requiredStar}</FormLabel>${hintJSX}\n <FormMessage />\n </div>\n </FormItem>\n )}\n />`\n\n case 'email':\n return generateTextFieldJSX(name, label, placeholder || 'email@example.com', hintJSX, requiredStar, 'email')\n\n case 'number':\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'number')\n\n case 'date':\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'date')\n\n case 'url':\n return generateTextFieldJSX(name, label, placeholder || 'https://', hintJSX, requiredStar, 'url')\n\n case 'phone':\n return generateTextFieldJSX(name, label, placeholder || '+1 (555) 000-0000', hintJSX, requiredStar, 'tel')\n\n case 'file':\n case 'upload':\n return generateFileUploadFieldJSX(field, name, label, hintJSX, requiredStar)\n\n case 'list':\n return generateListFieldJSX(field, name, label, hintPlainJSX, requiredStar)\n\n default:\n return generateTextFieldJSX(name, label, placeholder, hintJSX, requiredStar, 'text')\n }\n}\n\nexport function generateTextFieldJSX(\n name: string,\n label: string,\n placeholder: string,\n hintJSX: string,\n requiredStar: string,\n inputType: string\n): string {\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <Input type=\"${inputType}\" placeholder=\"${placeholder}\" {...field} />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n}\n\nfunction generateFileUploadFieldJSX(\n field: FormField,\n name: string,\n label: string,\n hintJSX: string,\n requiredStar: string\n): string {\n const accept = field.accept || '*/*'\n const maxSize = field.maxFileSize || 10\n return ` <FormField\n control={form.control}\n name=\"${name}\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>${label}${requiredStar}</FormLabel>\n <FormControl>\n <MediaUploadField\n value={field.value}\n onChange={field.onChange}\n onBlur={field.onBlur}\n accept=\"${accept}\"\n maxSizeInMB={${maxSize}}\n label=\"\"\n />\n </FormControl>${hintJSX}\n <FormMessage />\n </FormItem>\n )}\n />`\n}\n\nfunction generateListFieldJSX(\n field: FormField,\n name: string,\n label: string,\n hintJSX: string,\n requiredStar: string\n): string {\n if (!field.fields || field.fields.length === 0) {\n return generateTextFieldJSX(name, label, field.placeholder || '', hintJSX, requiredStar, 'text')\n }\n\n const singularLabel = singularize(label)\n\n const nestedFieldsJSX = field.fields\n .map((nf) => {\n const nfLabel = escapeJsx(nf.label || nf.name || '')\n const nfPlaceholder = nf.placeholder || ''\n\n if (nf.type === 'select' && nf.options && nf.options.length > 0) {\n const selectItems = nf.options\n .map(\n (opt) =>\n ` <SelectItem value=\"${opt.value}\">${escapeJsx(opt.label)}</SelectItem>`\n )\n .join('\\n')\n return ` <FormField\n control={form.control}\n name={\\`${name}.\\${index}.${nf.name}\\`}\n render={({ field: formField }) => (\n <FormItem className=\"flex-1\">\n <FormLabel>${nfLabel}</FormLabel>\n <Select onValueChange={formField.onChange} defaultValue={formField.value}>\n <FormControl>\n <SelectTrigger>\n <SelectValue placeholder=\"${nf.placeholder || 'Select...'}\" />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n${selectItems}\n </SelectContent>\n </Select>\n <FormMessage />\n </FormItem>\n )}\n />`\n }\n\n return ` <FormField\n control={form.control}\n name={\\`${name}.\\${index}.${nf.name}\\`}\n render={({ field: formField }) => (\n <FormItem className=\"flex-1\">\n <FormLabel>${nfLabel}</FormLabel>\n <FormControl>\n <Input type=\"text\" placeholder=\"${nfPlaceholder}\" {...formField} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />`\n })\n .join('\\n')\n\n const defaultObj = field.fields\n .map((nf) => {\n if (nf.type === 'select' || nf.type === 'radio') return `${nf.name}: undefined`\n if (nf.type === 'checkbox') return `${nf.name}: false`\n if (nf.type === 'number') return `${nf.name}: undefined`\n return `${nf.name}: ''`\n })\n .join(', ')\n\n return ` <div className=\"space-y-2\">\n <FormLabel className=\"text-sm font-medium leading-none\">${label}${requiredStar}</FormLabel>${hintJSX}\n {${name}FieldArray.fields.map((item, index) => (\n <div key={item.id} className=\"relative rounded-lg border p-4\">\n <button\n type=\"button\"\n onClick={() => ${name}FieldArray.remove(index)}\n className=\"absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-destructive/10 hover:text-destructive\"\n >\n <Trash2 className=\"size-4\" />\n <span className=\"sr-only\">Remove</span>\n </button>\n <div className=\"space-y-4 pr-8\">\n${nestedFieldsJSX}\n </div>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => ${name}FieldArray.append({ ${defaultObj} })}\n >\n Add ${singularLabel}\n </Button>\n </div>`\n}\n","/**\n * Drizzle ORM type mappings for schema fields and form fields\n */\n\nimport type { FormField, SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const DRIZZLE_DEFAULTS = {\n VARCHAR_LENGTH: 255,\n DECIMAL_PRECISION: 10,\n DECIMAL_SCALE: 2\n} as const\n\n// ============================================================================\n// Internal helpers\n// ============================================================================\n\n/**\n * Check if a field name suggests it's a URL field\n */\nfunction isUrlField(fieldName: string): boolean {\n const urlKeywords = ['url', 'link', 'href', 'website', 'avatar', 'logo', 'thumbnail']\n const lowerName = fieldName.toLowerCase()\n return urlKeywords.some((keyword) => lowerName.includes(keyword))\n}\n\n// ============================================================================\n// Schema Field → Drizzle Type (for database generator)\n// ============================================================================\n\n/**\n * Map a schema field type to Drizzle ORM column type\n * @param field - The schema field\n * @param requiredImports - Set to track which Drizzle imports are needed\n * @returns The Drizzle column type expression\n */\nexport function toDrizzleType(field: SchemaField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'serial':\n requiredImports.add('serial')\n return 'serial()'\n case 'string':\n case 'varchar':\n if (isUrlField(field.name) && !field.length) {\n requiredImports.add('text')\n return 'text()'\n }\n requiredImports.add('varchar')\n return field.length\n ? `varchar({ length: ${field.length} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'image':\n case 'video':\n case 'media':\n requiredImports.add('text')\n return 'text()'\n case 'text':\n case 'markdown':\n case 'richtext':\n requiredImports.add('text')\n return 'text()'\n case 'number':\n requiredImports.add('integer')\n return 'integer()'\n case 'decimal':\n requiredImports.add('decimal')\n if (field.precision && field.scale) {\n return `decimal({ precision: ${field.precision}, scale: ${field.scale} })`\n }\n return `decimal({ precision: ${DRIZZLE_DEFAULTS.DECIMAL_PRECISION}, scale: ${DRIZZLE_DEFAULTS.DECIMAL_SCALE} })`\n case 'boolean':\n requiredImports.add('boolean')\n return 'boolean()'\n case 'timestamp':\n requiredImports.add('timestamp')\n return \"timestamp({ precision: 3, mode: 'string' })\"\n case 'date':\n requiredImports.add('date')\n return \"date({ mode: 'string' })\"\n case 'time':\n case 'select':\n case 'icon':\n requiredImports.add('varchar')\n return field.length\n ? `varchar({ length: ${field.length} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'curriculum':\n requiredImports.add('jsonb')\n return `jsonb().$type<{ mode: 'sequential'; items: Array<{ title?: string; description?: string }> } | { mode: 'weekly'; weeks: Array<{ weekNumber: number; weekTitle?: string; weekDescription?: string; durationHours?: number; items: Array<{ title?: string; description?: string }> }> }>()`\n case 'list':\n requiredImports.add('jsonb')\n if (field.fields && field.fields.length > 0) {\n const nestedType = buildNestedListType(field.fields)\n return `jsonb().$type<Array<{ ${nestedType} }>>()`\n }\n return 'jsonb().$type<string[]>()'\n case 'relationship':\n requiredImports.add('integer')\n return 'integer()'\n default:\n requiredImports.add('text')\n return 'text()'\n }\n}\n\n/**\n * Build nested type string for list fields with nested fields\n */\nfunction buildNestedListType(fields: SchemaField[]): string {\n return fields\n .flatMap((f) => {\n let type: string\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n const innerType = f.fields\n .map((nf) => {\n let nfType: string\n if (nf.type === 'boolean') {\n nfType = 'boolean'\n } else if (nf.type === 'number' || nf.type === 'decimal') {\n nfType = 'number'\n } else {\n nfType = 'string'\n }\n return `${quotePropertyName(nf.name)}?: ${nfType}`\n })\n .join('; ')\n type = `Array<{ ${innerType} }>`\n } else if (f.type === 'list') {\n type = 'string[]'\n } else if (f.type === 'number' || f.type === 'decimal') {\n type = 'number'\n } else if (f.type === 'boolean') {\n type = 'boolean'\n } else {\n type = 'string'\n }\n const result = [`${quotePropertyName(f.name)}?: ${type}`]\n if (f.hasIcon) {\n result.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return result\n })\n .join('; ')\n}\n\n// ============================================================================\n// Form Field → Drizzle Type (for form-pipeline)\n// ============================================================================\n\n/**\n * Map a form field type to Drizzle ORM column type\n * @param field - The form field\n * @param requiredImports - Set to track which Drizzle imports are needed\n * @returns The Drizzle column type expression\n */\nexport function formFieldToDrizzleType(field: FormField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'text':\n requiredImports.add('varchar')\n return field.maxLength\n ? `varchar({ length: ${field.maxLength} })`\n : `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'textarea':\n requiredImports.add('text')\n return 'text()'\n case 'email':\n requiredImports.add('varchar')\n return `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'phone':\n requiredImports.add('varchar')\n return 'varchar({ length: 50 })'\n case 'number':\n requiredImports.add('integer')\n return 'integer()'\n case 'url':\n requiredImports.add('varchar')\n return 'varchar({ length: 500 })'\n case 'date':\n requiredImports.add('date')\n return \"date({ mode: 'string' })\"\n case 'select':\n case 'radio':\n case 'timezone':\n requiredImports.add('varchar')\n return `varchar({ length: ${DRIZZLE_DEFAULTS.VARCHAR_LENGTH} })`\n case 'checkbox':\n requiredImports.add('boolean')\n return 'boolean()'\n case 'multiselect':\n requiredImports.add('jsonb')\n return 'jsonb().$type<string[]>()'\n case 'list':\n requiredImports.add('jsonb')\n if (field.fields && field.fields.length > 0) {\n return 'jsonb().$type<Record<string, unknown>[]>()'\n }\n return 'jsonb().$type<string[]>()'\n case 'file':\n case 'upload':\n requiredImports.add('text')\n return 'text()'\n default:\n requiredImports.add('text')\n return 'text()'\n }\n}\n","/**\n * Zod validation type mappings for schema fields and form fields\n */\n\nimport type { FormField, SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\n// ============================================================================\n// Schema Field → Zod Type (for form validation)\n// ============================================================================\n\n/**\n * Map a schema field type to Zod validation schema\n * @param field - The schema field\n * @returns The Zod schema expression as a string\n */\nexport function toZodType(field: SchemaField): string {\n const label = field.label || field.name\n\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return field.required\n ? `z.number({ message: '${label} is required' })`\n : 'z.number().optional()'\n case 'boolean':\n return 'z.boolean()'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext': {\n if (field.name.toLowerCase().includes('email')) {\n const base = field.required\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().email('Please enter a valid email address').optional()`\n return field.length ? `${base}.max(${field.length})` : base\n }\n const base = field.required ? `z.string().min(1, '${label} is required')` : 'z.string()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'date':\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n return `z.string().min(1, '${label} is required')`\n case 'timestamp':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'image':\n case 'video':\n case 'media': {\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const mediaType =\n field.type === 'image' ? 'an image' : field.type === 'video' ? 'a video' : 'media'\n const base = `z.string().min(1, 'Please upload ${mediaType} for ${label}').url('Please provide a valid ${field.type} URL')`\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'list':\n return buildZodListType(field, label)\n case 'select': {\n if (field.options && field.options.length > 0) {\n const values = field.options.map((opt) => `'${opt.value}'`).join(', ')\n const valuesArray = `[${values}] as const`\n return field.required\n ? `z.string().min(1, '${label} is required').refine((val) => (${valuesArray} as readonly string[]).includes(val), { message: 'Invalid ${label}' })`\n : `z.string().refine((val) => !val || (${valuesArray} as readonly string[]).includes(val), { message: 'Invalid ${label}' }).optional()`\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'icon':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'relationship': {\n if (field.multiple) {\n return field.required\n ? `z.array(z.number()).min(1, '${label} is required')`\n : 'z.array(z.number()).optional()'\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'curriculum':\n return `z.object({\n mode: z.enum(['sequential', 'weekly']),\n items: z.array(z.object({\n title: z.string().max(255).optional(),\n description: z.string().max(500).optional()\n })).max(50),\n weeks: z.array(z.object({\n weekNumber: z.number().int().positive(),\n weekTitle: z.string().max(100).optional(),\n weekDescription: z.string().max(1000).optional(),\n durationHours: z.number().positive().optional(),\n items: z.array(z.object({\n title: z.string().max(255).optional(),\n description: z.string().max(500).optional()\n })).max(20)\n })).max(20)\n }).optional()`\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Build Zod type for list fields\n */\nfunction buildZodListType(field: SchemaField, label: string): string {\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .flatMap((nestedField) => {\n const defs: string[] = []\n const nestedZodType = toZodType(nestedField)\n const alreadyOptional = nestedZodType.includes('.optional()')\n let nestedDef = ` ${quotePropertyName(nestedField.name)}: ${nestedZodType}`\n if (!nestedField.required && !alreadyOptional) {\n nestedDef += '.optional()'\n }\n defs.push(nestedDef)\n if (nestedField.hasIcon) {\n defs.push(` ${quotePropertyName(`${nestedField.name}Icon`)}: z.string().optional()`)\n }\n return defs\n })\n .join(',\\n')\n const objectSchema = `z.object({\\n${nestedFields}\\n })`\n const arraySchema = field.maxItems\n ? `z.array(${objectSchema}).max(${field.maxItems}, '${label} cannot exceed ${field.maxItems} items')`\n : `z.array(${objectSchema})`\n return field.required\n ? `${arraySchema}.min(1, '${label} must have at least one item')`\n : `${arraySchema}.optional()`\n }\n if (field.items?.type === 'string' || field.items?.type === 'varchar') {\n const itemSchema = field.items.length ? `z.string().max(${field.items.length})` : 'z.string()'\n const arraySchema = field.maxItems\n ? `z.array(${itemSchema}).max(${field.maxItems}, '${label} cannot exceed ${field.maxItems} items')`\n : `z.array(${itemSchema})`\n return field.required\n ? `${arraySchema}.min(1, '${label} must have at least one item')`\n : `${arraySchema}.optional()`\n }\n return field.required\n ? `z.array(z.string()).min(1, '${label} must have at least one item')`\n : 'z.array(z.string()).optional()'\n}\n\n// ============================================================================\n// Form Field → Zod Type (for form-pipeline)\n// ============================================================================\n\nexport interface FormFieldZodOptions {\n treatAsOptional?: boolean\n}\n\n/**\n * Map a form field type to Zod validation schema\n * @param field - The form field\n * @param options - Options for generating the zod type\n * @returns The Zod schema expression as a string\n */\nexport function formFieldToZodType(field: FormField, options: FormFieldZodOptions = {}): string {\n const label = field.label\n const isRequired = field.required && !options.treatAsOptional\n\n switch (field.type) {\n case 'text': {\n let zodType = isRequired ? `z.string().min(1, '${label} is required')` : 'z.string()'\n if (field.minLength) {\n zodType += `.min(${field.minLength}, '${label} must be at least ${field.minLength} characters')`\n }\n if (field.maxLength) {\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n }\n if (field.pattern) {\n zodType += `.regex(new RegExp('${field.pattern}'), 'Invalid ${label} format')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'textarea': {\n let zodType = isRequired ? `z.string().min(1, '${label} is required')` : 'z.string()'\n if (field.minLength) {\n zodType += `.min(${field.minLength}, '${label} must be at least ${field.minLength} characters')`\n }\n if (field.maxLength) {\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'email':\n return isRequired\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || z.string().email().safeParse(val).success, { message: 'Please enter a valid email address' })`\n case 'phone': {\n const pattern =\n field.pattern || '^[+]?[(]?[0-9]{1,4}[)]?[-\\\\s\\\\.]?[(]?[0-9]{1,4}[)]?[-\\\\s\\\\.]?[0-9]{1,9}$'\n return isRequired\n ? `z.string().min(1, '${label} is required').regex(new RegExp('${pattern}'), 'Please enter a valid phone number')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || new RegExp('${pattern}').test(val), { message: 'Please enter a valid phone number' })`\n }\n case 'number': {\n let zodType = isRequired ? `z.number({ message: '${label} is required' })` : 'z.number()'\n if (field.min !== undefined) {\n zodType += `.min(${field.min}, '${label} must be at least ${field.min}')`\n }\n if (field.max !== undefined) {\n zodType += `.max(${field.max}, '${label} must be at most ${field.max}')`\n }\n return isRequired ? zodType : `${zodType}.optional()`\n }\n case 'url':\n return isRequired\n ? `z.string().min(1, '${label} is required').url('Please enter a valid URL')`\n : `z.string().optional().refine((val) => !val || val.trim() === '' || z.string().url().safeParse(val).success, { message: 'Please enter a valid URL' })`\n case 'date':\n return isRequired\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n case 'select':\n case 'radio':\n if (field.options && field.options.length > 0) {\n const values = field.options.map((opt) => `'${opt.value}'`).join(', ')\n return isRequired\n ? `z.enum([${values}], { message: '${label} is required' })`\n : `z.enum([${values}]).optional()`\n }\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'checkbox':\n return isRequired\n ? `z.boolean().refine(val => val === true, { message: '${label} is required' })`\n : 'z.boolean().optional()'\n case 'multiselect':\n return isRequired\n ? `z.array(z.string()).min(1, '${label} is required')`\n : 'z.array(z.string()).optional()'\n case 'timezone':\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((f) => `${f.name}: ${formFieldToZodType(f, options)}`)\n .join(', ')\n return isRequired\n ? `z.array(z.object({ ${nestedFields} })).min(1, '${label} is required')`\n : `z.array(z.object({ ${nestedFields} })).optional()`\n }\n return isRequired\n ? `z.array(z.string()).min(1, '${label} is required')`\n : 'z.array(z.string()).optional()'\n case 'file':\n case 'upload':\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n default:\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n","/**\n * TypeScript, form field, and SQL type mappings for schema fields\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize, quotePropertyName } from '../../utils/string.js'\nimport { DRIZZLE_DEFAULTS } from './drizzle.js'\n\n// ============================================================================\n// Schema Field → TypeScript Type (for actions generator)\n// ============================================================================\n\n/**\n * Map a schema field type to TypeScript type\n * @param field - The schema field\n * @param mode - 'input' for form input types, 'output' for database output types\n * @returns The TypeScript type as a string\n */\nexport function toTypeScriptType(field: SchemaField, mode: 'input' | 'output' = 'output'): string {\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return 'number'\n case 'boolean':\n return 'boolean'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext':\n case 'date':\n case 'time':\n case 'timestamp':\n case 'image':\n case 'video':\n case 'media':\n case 'icon':\n case 'select':\n return 'string'\n case 'relationship':\n if (mode === 'input') {\n return field.multiple ? 'number[]' : 'string'\n }\n if (field.relationship) {\n const relationshipSingular = singularize(field.relationship)\n const relationshipPascal = toPascalCase(relationshipSingular)\n return field.multiple ? `${relationshipPascal}Data[]` : `${relationshipPascal}Data | null`\n }\n return 'string'\n case 'group':\n if (field.fields && field.fields.length > 0) {\n const groupType = field.fields\n .map((f) => {\n const type = toTypeScriptType(f, mode)\n return `${quotePropertyName(f.name)}?: ${type}`\n })\n .join('; ')\n return `{ ${groupType} }`\n }\n return 'Record<string, unknown>'\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .flatMap((f) => {\n const type = toTypeScriptType(f, 'input')\n const fields = [`${quotePropertyName(f.name)}?: ${type}`]\n if (f.hasIcon) {\n fields.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return fields\n })\n .join('; ')\n return `Array<{ ${nestedType} }>`\n }\n return 'string[]'\n case 'curriculum':\n return '{ mode: \"sequential\" | \"weekly\"; items: Array<{ title?: string; description?: string }>; weeks: Array<{ weekNumber: number; weekTitle?: string; weekDescription?: string; durationHours?: number; items: Array<{ title?: string; description?: string }> }> }'\n default:\n return 'string'\n }\n}\n\n// ============================================================================\n// Schema Field → Form Field Type (for form generator)\n// ============================================================================\n\n/**\n * Map a schema field type to HTML form input type\n * @param field - The schema field\n * @returns The form input type (checkbox, textarea, number, date, etc.)\n */\nexport function toFormFieldType(field: SchemaField): string {\n switch (field.type) {\n case 'boolean':\n return 'checkbox'\n case 'text':\n return 'textarea'\n case 'markdown':\n return 'markdown'\n case 'richtext':\n return 'richtext'\n case 'number':\n case 'decimal':\n return 'number'\n case 'date':\n return 'date'\n case 'time':\n return 'time'\n case 'timestamp':\n return 'datetime-local'\n default:\n return 'text'\n }\n}\n\n// ============================================================================\n// Schema Field → SQL Type (for raw SQL migrations)\n// ============================================================================\n\n/**\n * Map a schema field type to SQL column type\n * @param field - The schema field\n * @returns The SQL column type\n */\nexport function toSQLType(field: SchemaField): string {\n switch (field.type) {\n case 'serial':\n return 'SERIAL'\n case 'string':\n case 'varchar':\n return field.length\n ? `VARCHAR(${field.length})`\n : `VARCHAR(${DRIZZLE_DEFAULTS.VARCHAR_LENGTH})`\n case 'text':\n case 'markdown':\n case 'richtext':\n case 'image':\n case 'video':\n case 'media':\n return 'TEXT'\n case 'number':\n return 'INTEGER'\n case 'decimal':\n return `DECIMAL(${field.precision || DRIZZLE_DEFAULTS.DECIMAL_PRECISION}, ${field.scale || DRIZZLE_DEFAULTS.DECIMAL_SCALE})`\n case 'boolean':\n return 'BOOLEAN'\n case 'timestamp':\n return 'TIMESTAMP(3)'\n case 'date':\n return 'DATE'\n case 'time':\n case 'select':\n case 'icon':\n return `VARCHAR(${DRIZZLE_DEFAULTS.VARCHAR_LENGTH})`\n case 'list':\n case 'curriculum':\n return 'JSONB'\n case 'relationship':\n return 'INTEGER'\n default:\n return 'TEXT'\n }\n}\n","/**\n * Single-step (flat) form component generator\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toKebabCase } from '../../utils/string.js'\nimport {\n type StepResult,\n resolveUiImport,\n escapeJsx,\n renderFieldsJSX,\n buildZodFields,\n buildDefaultValues,\n buildFieldArrayDecls,\n buildWatchDecls,\n getListFields,\n} from './form-component-shared.js'\n\nexport function generateSingleStepForm(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const fields = getAllFormSchemaFields(schema)\n\n const kebab = toKebabCase(formName)\n const filePath = path.join(cwd, cmsDir, 'components', 'forms', `${kebab}-form.tsx`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const zodFields = buildZodFields(fields)\n const defaults = buildDefaultValues(fields)\n const listFields = getListFields(fields)\n const hasListFields = listFields.length > 0\n const { setup: watchSetup } = buildWatchDecls(fields)\n\n const rawFields = schema.fields || []\n const fieldJSX = renderFieldsJSX(rawFields)\n\n const submitText = schema.submitButtonText || 'Submit'\n const successMessage = escapeJsx(schema.successMessage || 'Form submitted successfully!')\n\n const rhfImport = hasListFields\n ? `import { useFieldArray, useForm } from 'react-hook-form'`\n : `import { useForm } from 'react-hook-form'`\n\n const fieldArraySetup = hasListFields ? `\\n${buildFieldArrayDecls(listFields)}\\n` : ''\n\n const hasRadio = fields.some((f) => f.type === 'radio')\n const hasFileUpload = fields.some((f) => f.type === 'file' || f.type === 'upload')\n const buttonImport = resolveUiImport(cwd, 'button')\n const formImport = resolveUiImport(cwd, 'form')\n const inputImport = resolveUiImport(cwd, 'input')\n const textareaImport = resolveUiImport(cwd, 'textarea')\n const selectImport = resolveUiImport(cwd, 'select')\n const radioGroupImport = resolveUiImport(cwd, 'radio-group')\n const mediaUploadImport = resolveUiImport(cwd, 'media-upload-field')\n\n const queryClientImport = hasFileUpload\n ? `\\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'`\n : ''\n const queryClientSetup = hasFileUpload\n ? `\\nconst queryClient = new QueryClient()\\n`\n : ''\n\n const formComponentDecl = hasFileUpload ? `function ${pascal}FormInner` : `export function ${pascal}Form`\n const exportWrapper = hasFileUpload\n ? `\\nexport function ${pascal}Form() {\n return (\n <QueryClientProvider client={queryClient}>\n <${pascal}FormInner />\n </QueryClientProvider>\n )\n}\\n`\n : ''\n\n const lucideImport = hasListFields ? `\\nimport { Trash2 } from 'lucide-react'` : ''\n\n const content = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'${lucideImport}\nimport { useState } from 'react'\n${rhfImport}\nimport { z } from 'zod/v3'${queryClientImport}\nimport { create${pascal}Submission } from '@cms/actions/${kebab}-form'\nimport { Button } from '${buttonImport}'\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '${formImport}'\nimport { Input } from '${inputImport}'${hasFileUpload ? `\\nimport { MediaUploadField } from '${mediaUploadImport}'` : ''}${hasRadio ? `\\nimport { RadioGroup, RadioGroupItem } from '${radioGroupImport}'` : ''}\nimport { Textarea } from '${textareaImport}'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '${selectImport}'\n\nconst formSchema = z.object({\n${zodFields}\n})\n\ntype FormValues = z.infer<typeof formSchema>\n${queryClientSetup}\n${formComponentDecl}() {\n const [submitted, setSubmitted] = useState(false)\n const [submitting, setSubmitting] = useState(false)\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaults}\n },\n })\n${fieldArraySetup}${watchSetup}\n async function onSubmit(values: FormValues) {\n setSubmitting(true)\n try {\n const result = await create${pascal}Submission(values)\n if (result.success) {\n setSubmitted(true)\n } else {\n form.setError('root', { message: result.error || 'Something went wrong' })\n }\n } catch {\n form.setError('root', { message: 'Something went wrong. Please try again.' })\n } finally {\n setSubmitting(false)\n }\n }\n\n if (submitted) {\n return (\n <div className=\"rounded-lg border p-6 text-center\">\n <h3 className=\"text-lg font-semibold\">Thank you!</h3>\n <p className=\"mt-2 text-muted-foreground\">${successMessage}</p>\n </div>\n )\n }\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n${fieldJSX}\n\n {form.formState.errors.root && (\n <p className=\"text-sm text-destructive\">{form.formState.errors.root.message}</p>\n )}\n\n <Button type=\"submit\" disabled={submitting}>\n {submitting ? 'Submitting...' : '${submitText}'}\n </Button>\n </form>\n </Form>\n )\n}\n${exportWrapper}`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Form pipeline step 4: Public form component generation\n * Routes to single-step or multi-step generator based on schema structure.\n */\n\nimport { isMultiStepForm } from '../../core/field-helpers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport type { StepResult } from './form-component-shared.js'\nimport { generateMultiStepForm } from './form-component-multistep.js'\nimport { generateSingleStepForm } from './form-component-single.js'\n\nexport function generateFormComponent(\n schema: FormSchema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions\n): StepResult {\n if (isMultiStepForm(schema) && schema.steps!.length > 1) {\n return generateMultiStepForm(schema, cwd, cmsDir, options)\n }\n return generateSingleStepForm(schema, cwd, cmsDir, options)\n}\n","/**\n * Form pipeline step 1: Database schema generation for form submissions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { getAllFormSchemaFields, hasDynamicFields } from '../../core/field-helpers/index.js'\nimport { formFieldToDrizzleType } from '../../core/type-mappers/index.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase } from '../../utils/string.js'\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n // Skip optional semicolon and trailing whitespace\n let end = i + 1\n while (end < content.length && (content[end] === ';' || content[end] === ' ' || content[end] === '\\t')) {\n end++\n }\n if (end < content.length && content[end] === '\\n') {\n end++\n }\n return end\n }\n }\n\n return content.length\n}\n\ninterface StepResult {\n files: string[]\n}\n\nexport function generateFormDatabase(\n schema: FormSchema,\n cwd: string,\n dbSchemaPath: string,\n options: GeneratorOptions\n): StepResult {\n const tableName = `${toCamelCase(schema.name)}Submissions`\n const fields = getAllFormSchemaFields(schema)\n const includeDynamic = hasDynamicFields(schema)\n\n const requiredImports = new Set<string>(['serial', 'timestamp', 'text'])\n if (includeDynamic) requiredImports.add('jsonb')\n\n // Generate field definitions\n const fieldDefs = fields\n .map((field) => {\n const drizzleType = formFieldToDrizzleType(field, requiredImports)\n return ` ${field.name}: ${drizzleType},`\n })\n .join('\\n')\n\n const customFieldsCol = includeDynamic\n ? '\\n customFields: jsonb().$type<Record<string, unknown>>(),'\n : ''\n\n const tableSchema = `\nexport const ${tableName} = pgTable('${toPascalCase(schema.name)}Submissions', {\n id: serial().primaryKey().notNull(),\n${fieldDefs}${customFieldsCol}\n ipAddress: text(),\n userAgent: text(),\n submittedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull(),\n createdAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull(),\n updatedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()\n})\n`\n\n const filePath = path.join(cwd, dbSchemaPath)\n let content = fs.readFileSync(filePath, 'utf-8')\n\n // Merge imports\n const pgCoreMatch = content.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/)\n if (pgCoreMatch) {\n const existing = new Set(\n pgCoreMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n )\n const merged = Array.from(new Set([...existing, ...requiredImports])).sort()\n content = content.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n `import {\\n ${merged.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n )\n }\n\n // Ensure sql import\n if (!content.includes('import { sql }')) {\n content = content.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n (match) => `import { sql } from 'drizzle-orm'\\n${match}`\n )\n }\n\n // Remove all existing table definitions if --force (handles prior duplicates)\n if (content.includes(`export const ${tableName}`)) {\n if (!options.force) {\n return { files: [dbSchemaPath] }\n }\n const marker = `export const ${tableName} =`\n let start = content.indexOf(marker)\n while (start !== -1) {\n const end = findTableEnd(content, start)\n const actualStart = start > 0 && content[start - 1] === '\\n' ? start - 1 : start\n content = content.slice(0, actualStart) + content.slice(end)\n start = content.indexOf(marker)\n }\n }\n\n content += `\\n${tableSchema}`\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return { files: [dbSchemaPath] }\n}\n","/**\n * Form pipeline step 3: React Query hook for form submissions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { toPascalCase, toCamelCase, toKebabCase } from '../../utils/string.js'\n\ninterface StepResult {\n files: string[]\n}\n\nexport function generateFormHook(\n schema: FormSchema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions\n): StepResult {\n const formName = schema.name\n const pascal = toPascalCase(formName)\n const camel = toCamelCase(formName)\n const kebab = toKebabCase(formName)\n\n const filePath = path.join(cwd, hooksDir, `use-${kebab}-form.ts`)\n const dir = path.dirname(filePath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [path.relative(cwd, filePath)] }\n }\n\n const successMsg = (schema.successMessage || 'Form submitted successfully').replace(/'/g, \"\\\\'\")\n\n const content = `import {\n create${pascal}Submission,\n delete${pascal}Submission,\n export${pascal}SubmissionsCSV,\n export${pascal}SubmissionsJSON,\n get${pascal}Submission,\n get${pascal}Submissions,\n} from '@cms/actions/${kebab}-form'\nimport type { Create${pascal}SubmissionInput } from '@cms/actions/${kebab}-form'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { toast } from 'sonner'\n\nexport function use${pascal}Submissions(search?: string) {\n return useQuery({\n queryKey: ['${camel}-submissions', search ?? ''],\n queryFn: () => get${pascal}Submissions()\n })\n}\n\nexport function use${pascal}Submission(id: number | null) {\n return useQuery({\n queryKey: ['${camel}-submission', id],\n queryFn: () => get${pascal}Submission(id!),\n enabled: !!id\n })\n}\n\nexport function useCreate${pascal}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (data: Create${pascal}SubmissionInput) => create${pascal}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${successMsg}')\n await queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n } else {\n toast.error(result.error || 'Failed to submit form')\n }\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to submit form')\n }\n })\n}\n\nexport function useDelete${pascal}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: number) => delete${pascal}Submission(id),\n onSuccess: async () => {\n toast.success('Submission deleted successfully')\n await queryClient.refetchQueries({ queryKey: ['${camel}-submissions'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to delete submission')\n }\n })\n}\n\nexport function useExport${pascal}SubmissionsCSV() {\n return useMutation({\n mutationFn: export${pascal}SubmissionsCSV,\n onSuccess: (csvContent) => {\n const blob = new Blob([csvContent], { type: 'text/csv' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = '${formName}-submissions-' + new Date().toISOString().split('T')[0] + '.csv'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n window.URL.revokeObjectURL(url)\n toast.success('CSV exported successfully')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to export CSV')\n }\n })\n}\n\nexport function useExport${pascal}SubmissionsJSON() {\n return useMutation({\n mutationFn: export${pascal}SubmissionsJSON,\n onSuccess: (jsonContent) => {\n const blob = new Blob([jsonContent], { type: 'application/json' })\n const url = window.URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = '${formName}-submissions-' + new Date().toISOString().split('T')[0] + '.json'\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n window.URL.revokeObjectURL(url)\n toast.success('JSON exported successfully')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to export JSON')\n }\n })\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n return { files: [path.relative(cwd, filePath)] }\n}\n","/**\n * Form pipeline orchestrator — runs all form generation steps in sequence\n */\n\nimport type { BetterstartConfig } from '../../config/types.js'\nimport type { FormSchema, GeneratorOptions } from '../../types.js'\nimport { generateEmailTemplate } from '../email-template.js'\nimport { generateFormAdminPages } from '../form-admin/index.js'\nimport { updateFormNavigation } from '../form-navigation.js'\nimport { generateFormActions } from './form-actions.js'\nimport { generateFormComponent } from './form-component.js'\nimport { generateFormDatabase } from './form-database.js'\nimport { generateFormHook } from './form-hook.js'\n\nexport interface FormPipelineResult {\n success: boolean\n files: string[]\n errors: string[]\n}\n\n/**\n * Resolve output paths from config for form generation\n */\nfunction resolveFormPaths(config: BetterstartConfig) {\n const cms = config.paths?.cms ?? './cms'\n const pages = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n return {\n cmsDir: cms,\n pagesDir: pages,\n dbSchemaPath: `${cms}/db/schema.ts`,\n actionsDir: `${cms}/lib/actions`,\n hooksDir: `${cms}/hooks`\n }\n}\n\n/**\n * Run the form generation pipeline\n */\nexport function runFormPipeline(\n schema: FormSchema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): FormPipelineResult {\n const paths = resolveFormPaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema (submissions)',\n run: () => generateFormDatabase(schema, cwd, paths.dbSchemaPath, options).files\n },\n {\n name: 'Server actions',\n run: () => generateFormActions(schema, cwd, paths.actionsDir, options).files\n },\n {\n name: 'React Query hook',\n run: () => generateFormHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Public form component',\n run: () => generateFormComponent(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Admin pages',\n run: () => generateFormAdminPages(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Navigation',\n run: () => updateFormNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Email template',\n run: () => generateEmailTemplate(schema, cwd, paths.cmsDir, options).files\n }\n ]\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return { success: errors.length === 0, files, errors }\n}\n","/**\n * Generator 2: Server actions — cms/lib/actions/<name>/\n * Generates 'use server' CRUD actions for an entity schema,\n * split into individual files with a barrel index.ts.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields, getManyToManyFields } from '../../core/field-helpers/index.js'\nimport type { Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toKebabCase, quotePropertyName } from '../../utils/string.js'\nimport type { ActionsGeneratorResult } from './action-helpers.js'\nimport {\n generateFieldMapping,\n getFieldType,\n buildRelationshipSelect,\n buildResultMapping,\n buildSingleRowMapping,\n buildExplicitSelect,\n findListFieldsWithRelationships,\n generatePopulateListRelsFunction\n} from './action-helpers.js'\nimport type { EntityCtx } from './entity-file-contents.js'\nimport {\n genTypesContent,\n genHelpersContent,\n genGetPluralContent,\n genGetByIdContent,\n genGetBySlugContent,\n genCreateContent,\n genUpdateContent,\n genDeleteContent,\n genDeleteBulkContent,\n genSortOrderContent,\n genBulkSortOrderContent,\n genM2MFiles,\n genDistinctFiles,\n genBarrelContent\n} from './entity-file-contents.js'\n\n/**\n * Generate server action files for an entity, split into individual files.\n */\nexport function generateActions(\n schema: Schema,\n cwd: string,\n actionsDir: string,\n options: { force?: boolean; schemasDir?: string } = {}\n): ActionsGeneratorResult {\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, schema.name)\n const oldFilePath = path.join(absActionsDir, `${schema.name}.ts`)\n\n // Check existence: both old single-file format and new directory format\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n // Force: clean up old file and stale directory\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n const ctx = buildEntityContext(schema)\n\n // Build all file entries\n const kebabSingular = toKebabCase(ctx.singular)\n const kebabPlural = toKebabCase(ctx.plural)\n const files: Array<{ name: string; content: string }> = []\n\n files.push({ name: 'types.ts', content: genTypesContent(ctx) })\n\n const helpersContent = genHelpersContent(ctx)\n if (helpersContent) {\n files.push({ name: 'helpers.ts', content: helpersContent })\n }\n\n files.push({ name: `get-${kebabPlural}.ts`, content: genGetPluralContent(ctx) })\n files.push({ name: `get-${kebabSingular}-by-id.ts`, content: genGetByIdContent(ctx) })\n\n const bySlugContent = genGetBySlugContent(ctx)\n if (bySlugContent) {\n files.push({ name: `get-${kebabSingular}-by-slug.ts`, content: bySlugContent })\n }\n\n files.push({ name: `create-${kebabSingular}.ts`, content: genCreateContent(ctx) })\n files.push({ name: `update-${kebabSingular}.ts`, content: genUpdateContent(ctx) })\n files.push({ name: `delete-${kebabSingular}.ts`, content: genDeleteContent(ctx) })\n files.push({ name: `delete-bulk-${kebabPlural}.ts`, content: genDeleteBulkContent(ctx) })\n files.push({ name: `update-${kebabSingular}-sort-order.ts`, content: genSortOrderContent(ctx) })\n files.push({ name: `bulk-update-${kebabPlural}-sort-order.ts`, content: genBulkSortOrderContent(ctx) })\n\n // M2M files (conditional, per relationship)\n files.push(...genM2MFiles(ctx))\n\n // Distinct filter files (conditional, per filter field)\n files.push(...genDistinctFiles(ctx))\n\n // Barrel index.ts (must be last, references other files)\n files.push({ name: 'index.ts', content: genBarrelContent(files, ctx) })\n\n // Write all files\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.join(actionsDir, schema.name, f.name)) }\n}\n\n// ============================================================================\n// Context builder — computes all shared state for content generators\n// ============================================================================\n\nfunction buildEntityContext(schema: Schema): EntityCtx {\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const tableVar = toCamelCase(schema.name)\n const camelPlural = toCamelCase(plural)\n const camelSingular = toCamelCase(singular)\n\n const dbFields = flattenFields(schema.fields).filter((f) => !isLayoutField(f.type))\n const m2mFields = getManyToManyFields(schema.fields)\n const hasM2M = m2mFields.length > 0\n\n const relationshipFields = dbFields.filter(\n (f) => f.type === 'relationship' && f.relationship && !f.multiple\n )\n const hasRelationships = relationshipFields.length > 0\n\n const regularDbFields = dbFields.filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n const listFieldsWithRels = findListFieldsWithRelationships(dbFields)\n const hasListRels = listFieldsWithRels.length > 0\n\n const allListRelQueries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n listFieldName: string\n }> = []\n\n for (const { field: listField, path: fieldPath } of listFieldsWithRels) {\n const rels = (listField.fields || []).filter((f) => f.type === 'relationship' && f.relationship)\n for (const relField of rels) {\n allListRelQueries.push({\n fieldPath: fieldPath.join('_'),\n relField,\n relTable: toCamelCase(relField.relationship!),\n listFieldName: listField.name\n })\n }\n }\n\n const populateListRelsFn = hasListRels\n ? generatePopulateListRelsFunction(allListRelQueries, Singular)\n : ''\n\n const htmlOutputFields = regularDbFields.filter(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n const hasHtmlOutput = htmlOutputFields.length > 0\n\n const hasSlug = regularDbFields.some((f) => f.name === 'slug')\n const hasDraft = schema.actions?.draft === true\n const hasPublished = regularDbFields.some((f) => f.name === 'published')\n const hasSearch = (schema.search?.fields || []).length > 0\n const searchFields = schema.search?.fields || []\n const hasFilters = (schema.filters || []).length > 0\n const hasAutoSlug = schema.autoSlugify?.enabled === true\n\n // Build allDbFields (with auto-added fields)\n const allDbFields = [...regularDbFields]\n if (hasDraft && !hasPublished) {\n allDbFields.push({ name: 'published', type: 'boolean' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'createdAt')) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'updatedAt')) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n if (!regularDbFields.some((f) => f.name === 'sortOrder')) {\n allDbFields.push({ name: 'sortOrder', type: 'number' as const, required: true })\n }\n\n const listExcludeFields = new Set(htmlOutputFields.map((f) => f.name))\n const listDbFields = hasHtmlOutput\n ? allDbFields.filter((f) => !listExcludeFields.has(f.name))\n : allDbFields\n\n const createFields = regularDbFields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'sortOrder'\n )\n\n const filterableFields = allDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'sortOrder' &&\n ['string', 'varchar', 'text', 'boolean', 'number', 'decimal'].includes(f.type)\n )\n\n // Per-file DB imports\n const relTableImports = relationshipFields.map((f) => toCamelCase(f.relationship!))\n const listRelTableImports = allListRelQueries.map((q) => q.relTable)\n\n // --- Build interfaces ---\n const dataFields = allDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const m2mFieldTypes = m2mFields.map((f) => ` ${quotePropertyName(f.name)}: number[]`).join('\\n')\n const htmlFieldTypes = htmlOutputFields.map((f) => ` ${f.name}Html: string`).join('\\n')\n\n const dataInterface = `export interface ${Singular}Data {\\n${dataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\\n}`\n\n const displayDbFields = allDbFields.filter((f) => !htmlOutputFields.some((h) => h.name === f.name))\n const displayDataFields = displayDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const displayDataInterface = hasHtmlOutput\n ? `export interface ${Singular}DisplayData {\\n${displayDataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\\n}`\n : ''\n\n const responseInterface = `export interface ${Plural}Response {\\n ${camelPlural}: ${Singular}Data[]\\n total: number\\n}`\n\n const filtersInterfaceFields = filterableFields\n .map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f)}`)\n .join('\\n')\n const filtersInterface = `export interface Get${Plural}Filters {\\n search?: string\\n${filtersInterfaceFields}\\n limit?: number\\n}`\n\n const createInterfaceFields = createFields\n .map(\n (f) => ` ${quotePropertyName(f.name)}${f.required ? '' : '?'}: ${getFieldType(f, 'input')}`\n )\n .join('\\n')\n const createInterface = `export interface Create${Singular}Input {\\n${createInterfaceFields}${hasDraft ? `\\n published?: boolean` : ''}\\n}`\n\n const updateInterfaceFields = createFields\n .map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`)\n .join('\\n')\n const updateInterface = `export interface Update${Singular}Input {\\n id: number\\n${updateInterfaceFields}${hasDraft ? `\\n published?: boolean` : ''}\\n}`\n\n // --- Build select clauses ---\n const selectClause = hasRelationships\n ? buildRelationshipSelect(allDbFields, relationshipFields, tableVar)\n : `db.select().from(${tableVar})`\n\n const listSelectClause = hasHtmlOutput\n ? hasRelationships\n ? buildRelationshipSelect(listDbFields, relationshipFields, tableVar)\n : buildExplicitSelect(listDbFields, tableVar)\n : selectClause\n\n const displaySelectClause =\n hasHtmlOutput && hasSlug\n ? hasRelationships\n ? buildRelationshipSelect(displayDbFields, relationshipFields, tableVar, htmlOutputFields)\n : buildExplicitSelect(displayDbFields, tableVar, htmlOutputFields)\n : selectClause\n\n // --- Build query parts ---\n const filterConditions = filterableFields\n .map((f) =>\n f.type === 'boolean'\n ? ` if (filters?.${f.name} !== undefined) {\\n conditions.push(eq(${tableVar}.${f.name}, filters.${f.name}))\\n }`\n : ` if (filters?.${f.name}) {\\n conditions.push(eq(${tableVar}.${f.name}, filters.${f.name}))\\n }`\n )\n .join('\\n')\n\n const searchBlock = hasSearch\n ? ` const search = filters?.search\\n if (search && typeof search === 'string' && search.trim()) {\\n const searchTerm = \\`%\\${search.trim().toLowerCase()}%\\`\\n conditions.push(\\n or(\\n${searchFields.map((f) => ` ilike(${tableVar}.${f}, searchTerm)`).join(',\\n')}\\n )\\n )\\n }\\n`\n : ''\n\n const resultMapping = hasRelationships\n ? buildResultMapping(allDbFields, relationshipFields, Plural, camelPlural, Singular, hasListRels)\n : hasListRels\n ? `\\n\\n const populated${Plural} = await Promise.all(\\n results.map(record => populate${Singular}ListRelationships(record as ${Singular}Data))\\n )\\n\\n return {\\n ${camelPlural}: populated${Plural},\\n total: populated${Plural}.length\\n }`\n : `\\n return {\\n ${camelPlural}: results as ${Singular}Data[],\\n total: results.length\\n }`\n\n const listResultMapping =\n hasHtmlOutput && hasRelationships\n ? buildResultMapping(\n listDbFields,\n relationshipFields,\n Plural,\n camelPlural,\n Singular,\n hasListRels\n )\n : resultMapping\n\n const fieldMeta = createFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const createMappings = createFields\n .map((f) => ` ${f.name}: ${generateFieldMapping(f)}`)\n .join(',\\n')\n\n const htmlCreateBlock = hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n htmlOutputFields\n .map((f) => ` const ${f.name}Html = renderMarkdownSync(input.${f.name} || '')`)\n .join('\\n') +\n '\\n'\n : ''\n\n const htmlCreateMappings = htmlOutputFields.map((f) => ` ${f.name}Html`).join(',\\n')\n\n const autoSlugCreate = hasAutoSlug\n ? `\\n if ((!input.${schema.autoSlugify!.targetField} || input.${schema.autoSlugify!.targetField} === '') && input.${schema.autoSlugify!.sourceField}) {\\n input.${schema.autoSlugify!.targetField} = slugify(input.${schema.autoSlugify!.sourceField})\\n }\\n`\n : ''\n const autoSlugUpdate = hasAutoSlug\n ? `\\n if (updateData.${schema.autoSlugify!.sourceField}) {\\n if (updateData.${schema.autoSlugify!.targetField} === '' || updateData.${schema.autoSlugify!.targetField} === undefined) {\\n updateData.${schema.autoSlugify!.targetField} = slugify(updateData.${schema.autoSlugify!.sourceField})\\n }\\n }\\n`\n : ''\n\n const cacheTag = `${plural}:all`\n\n // --- Build single row returns ---\n const singleRowReturn = (() => {\n if (hasRelationships && hasListRels) {\n return `const row = result[0]\\n return await populate${Singular}ListRelationships(${buildSingleRowMapping(allDbFields, relationshipFields, `${Singular}Data`)})`\n }\n if (hasRelationships) {\n return `const row = result[0]\\n return ${buildSingleRowMapping(allDbFields, relationshipFields, `${Singular}Data`)}`\n }\n if (hasListRels) {\n return `return await populate${Singular}ListRelationships(result[0] as ${Singular}Data)`\n }\n return `return result[0] as ${Singular}Data`\n })()\n\n const displaySingleRowReturn = hasHtmlOutput\n ? (() => {\n const displayType = `${Singular}DisplayData`\n if (hasRelationships && hasListRels) {\n return `const row = result[0]\\n return await populate${Singular}ListRelationships(${buildSingleRowMapping(displayDbFields, relationshipFields, `${Singular}Data`, htmlOutputFields)}) as unknown as ${displayType}`\n }\n if (hasRelationships) {\n return `const row = result[0]\\n return ${buildSingleRowMapping(displayDbFields, relationshipFields, displayType, htmlOutputFields)}`\n }\n if (hasListRels) {\n return `return await populate${Singular}ListRelationships(result[0] as unknown as ${Singular}Data) as unknown as ${displayType}`\n }\n return `return result[0] as ${displayType}`\n })()\n : singleRowReturn\n\n return {\n singular,\n plural,\n Singular,\n Plural,\n tableVar,\n camelSingular,\n camelPlural,\n cacheTag,\n hasRelationships,\n hasM2M,\n hasListRels,\n hasHtmlOutput,\n hasSlug,\n hasDraft,\n hasSearch,\n hasFilters,\n hasAutoSlug,\n searchFields,\n htmlOutputFields,\n m2mFields,\n filterableFields,\n relTableImports,\n listRelTableImports,\n dataInterface,\n displayDataInterface,\n responseInterface,\n filtersInterface,\n createInterface,\n updateInterface,\n selectClause,\n listSelectClause,\n displaySelectClause,\n filterConditions,\n searchBlock,\n resultMapping,\n listResultMapping,\n singleRowReturn,\n displaySingleRowReturn,\n fieldMeta,\n createMappings,\n htmlCreateBlock,\n htmlCreateMappings,\n autoSlugCreate,\n autoSlugUpdate,\n populateListRelsFn,\n filters: schema.filters || []\n }\n}\n","/**\n * Centralized constants for the codegen system\n * Replaces magic strings scattered throughout generators\n */\n\n// ============================================================================\n// Field Types\n// ============================================================================\n\nexport const FIELD_TYPES = {\n STRING: 'string',\n NUMBER: 'number',\n BOOLEAN: 'boolean',\n TEXT: 'text',\n DECIMAL: 'decimal',\n VARCHAR: 'varchar',\n SERIAL: 'serial',\n DATE: 'date',\n TIMESTAMP: 'timestamp',\n TIME: 'time',\n MARKDOWN: 'markdown',\n IMAGE: 'image',\n VIDEO: 'video',\n MEDIA: 'media',\n ICON: 'icon',\n GROUP: 'group',\n TABS: 'tabs',\n LIST: 'list',\n SEPARATOR: 'separator',\n SECTION: 'section',\n SELECT: 'select',\n RELATIONSHIP: 'relationship',\n CURRICULUM: 'curriculum'\n} as const\n\nexport const LAYOUT_FIELD_TYPES = [FIELD_TYPES.SEPARATOR] as const\n\nexport const NESTED_FIELD_TYPES = [FIELD_TYPES.GROUP, FIELD_TYPES.TABS, FIELD_TYPES.LIST] as const\n\nexport const RICH_TEXT_FIELD_TYPES = [FIELD_TYPES.MARKDOWN, FIELD_TYPES.TEXT] as const\n\nexport const LONG_TEXT_FIELD_TYPES = [\n FIELD_TYPES.TEXT,\n FIELD_TYPES.MARKDOWN,\n FIELD_TYPES.LIST,\n FIELD_TYPES.MEDIA,\n FIELD_TYPES.VIDEO,\n FIELD_TYPES.CURRICULUM\n] as const\n\n// ============================================================================\n// Column Types\n// ============================================================================\n\nexport const COLUMN_TYPES = {\n TEXT: 'text',\n BADGE: 'badge',\n DATE: 'date',\n CUSTOM: 'custom',\n AVATAR: 'avatar',\n LINK: 'link',\n IMAGE: 'image',\n EMAIL: 'email',\n NUMBER: 'number',\n BOOLEAN: 'boolean'\n} as const\n\n// ============================================================================\n// Form Field Types\n// ============================================================================\n\nexport const FORM_FIELD_TYPES = {\n TEXT: 'text',\n TEXTAREA: 'textarea',\n EMAIL: 'email',\n PHONE: 'phone',\n NUMBER: 'number',\n URL: 'url',\n DATE: 'date',\n SELECT: 'select',\n RADIO: 'radio',\n CHECKBOX: 'checkbox',\n MULTISELECT: 'multiselect',\n FILE: 'file',\n UPLOAD: 'upload',\n GROUP: 'group',\n TIMEZONE: 'timezone',\n LIST: 'list'\n} as const\n\n// ============================================================================\n// Auto-generated Fields\n// ============================================================================\n\nexport const AUTO_FIELDS = {\n ID: 'id',\n CREATED_AT: 'createdAt',\n UPDATED_AT: 'updatedAt',\n PUBLISHED: 'published',\n SLUG: 'slug'\n} as const\n\nexport const FORM_SUBMISSION_FIELDS = {\n SUBMITTED_AT: 'submittedAt',\n IP_ADDRESS: 'ipAddress',\n USER_AGENT: 'userAgent'\n} as const\n\n// ============================================================================\n// Database Constants\n// ============================================================================\n\nexport const DRIZZLE_DEFAULTS = {\n VARCHAR_LENGTH: 255,\n DECIMAL_PRECISION: 10,\n DECIMAL_SCALE: 2\n} as const\n\n// ============================================================================\n// Generator Names\n// ============================================================================\n\nexport const CORE_GENERATORS = [\n 'database',\n 'actions',\n 'hooks',\n 'columns',\n 'table',\n 'page',\n 'page-content',\n 'form',\n 'create-page',\n 'edit-page',\n 'navigation'\n] as const\n\n// ============================================================================\n// File Extensions\n// ============================================================================\n\nexport const FILE_EXTENSIONS = {\n TYPESCRIPT: '.ts',\n TSX: '.tsx',\n JSON: '.json',\n SQL: '.sql'\n} as const\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\nexport type FieldTypeValue = (typeof FIELD_TYPES)[keyof typeof FIELD_TYPES]\nexport type ColumnTypeValue = (typeof COLUMN_TYPES)[keyof typeof COLUMN_TYPES]\nexport type FormFieldTypeValue = (typeof FORM_FIELD_TYPES)[keyof typeof FORM_FIELD_TYPES]\n\nexport function isFieldType(value: string): value is FieldTypeValue {\n return Object.values(FIELD_TYPES).includes(value as FieldTypeValue)\n}\n\nexport function isLayoutField(type: string): boolean {\n return (LAYOUT_FIELD_TYPES as readonly string[]).includes(type)\n}\n\nexport function isNestedFieldType(type: string): boolean {\n return (NESTED_FIELD_TYPES as readonly string[]).includes(type)\n}\n\nexport function isLongTextFieldType(type: string): boolean {\n return (LONG_TEXT_FIELD_TYPES as readonly string[]).includes(type)\n}\n","/**\n * Shared helpers for entity and single action generators\n */\n\nimport { toTypeScriptType } from '../../core/type-mappers/index.js'\nimport type { SchemaField } from '../../types.js'\nimport { toCamelCase } from '../../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface ActionsGeneratorResult {\n files: string[]\n}\n\n// ============================================================================\n// Field Mapping Helpers\n// ============================================================================\n\nexport function generateFieldMapping(field: SchemaField, source = 'input'): string {\n if (field.type === 'list') return `${source}.${field.name} || []`\n if (\n (field.type === 'date' || field.type === 'timestamp' || field.type === 'time') &&\n !field.required\n ) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n if (!field.required && ['string', 'varchar', 'text', 'select'].includes(field.type)) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n return `${source}.${field.name}`\n}\n\nexport function getFieldType(field: SchemaField, mode: 'input' | 'output' = 'output'): string {\n return toTypeScriptType(field, mode)\n}\n\n// ============================================================================\n// Helper builders for relationship queries\n// ============================================================================\n\nexport function buildRelationshipSelect(\n allDbFields: SchemaField[],\n relationshipFields: SchemaField[],\n tableVar: string,\n htmlFields: SchemaField[] = []\n): string {\n const fieldSelects = allDbFields\n .filter((f) => f.type !== 'relationship')\n .map((f) => ` ${f.name}: ${tableVar}.${f.name}`)\n const htmlSelects = htmlFields.map((f) => ` ${f.name}Html: ${tableVar}.${f.name}Html`)\n const regularSelects = [...fieldSelects, ...htmlSelects].join(',\\n')\n\n const relSelects = relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return ` ${f.name}: { id: ${relTable}.id, name: ${relTable}.name, title: ${relTable}.title, slug: ${relTable}.slug, label: ${relTable}.label }`\n })\n .join(',\\n')\n\n const joins = relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return `.leftJoin(${relTable}, sql\\`CAST(NULLIF(\\${${tableVar}.${f.name}}, '') AS INTEGER) = \\${${relTable}.id}\\`)`\n })\n .join('')\n\n return `db.select({\\n${regularSelects},\\n${relSelects}\\n }).from(${tableVar})${joins}`\n}\n\nexport function buildResultMapping(\n allDbFields: SchemaField[],\n _relationshipFields: SchemaField[],\n Plural: string,\n camelPlural: string,\n Singular: string,\n hasListRels = false\n): string {\n const rowMappings = allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n return ` ${f.name}: row.${f.name}?.id ? { id: row.${f.name}.id, name: row.${f.name}.name ?? undefined, title: row.${f.name}.title ?? undefined, slug: row.${f.name}.slug ?? undefined, label: row.${f.name}.label ?? undefined } : null`\n }\n return ` ${f.name}: row.${f.name}`\n })\n .join(',\\n')\n\n const mapBlock = `\n\n const mapped${Plural} = results.map((row) => ({\n${rowMappings}\n }))`\n\n if (hasListRels) {\n return `${mapBlock}\n\n const populated${Plural} = await Promise.all(\n mapped${Plural}.map(record => populate${Singular}ListRelationships(record as ${Singular}Data))\n )\n\n return {\n ${camelPlural}: populated${Plural},\n total: populated${Plural}.length\n }`\n }\n\n return `${mapBlock}\n\n return {\n ${camelPlural}: mapped${Plural} as ${Singular}Data[],\n total: mapped${Plural}.length\n }`\n}\n\nexport function buildSingleRowMapping(\n allDbFields: SchemaField[],\n _relationshipFields: SchemaField[],\n typeName: string,\n htmlFields: SchemaField[] = []\n): string {\n const fieldMappings = allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n return ` ${f.name}: row.${f.name}?.id ? { id: row.${f.name}.id, name: row.${f.name}.name ?? undefined, title: row.${f.name}.title ?? undefined, slug: row.${f.name}.slug ?? undefined, label: row.${f.name}.label ?? undefined } : null`\n }\n return ` ${f.name}: row.${f.name}`\n })\n const htmlMappings = htmlFields.map((f) => ` ${f.name}Html: row.${f.name}Html`)\n const mappings = [...fieldMappings, ...htmlMappings].join(',\\n')\n\n return `{\\n${mappings}\\n } as ${typeName}`\n}\n\nexport function buildExplicitSelect(fields: SchemaField[], tableVar: string, htmlFields: SchemaField[] = []): string {\n const fieldSelects = fields.map((f) => ` ${f.name}: ${tableVar}.${f.name}`)\n const htmlSelects = htmlFields.map((f) => ` ${f.name}Html: ${tableVar}.${f.name}Html`)\n const selects = [...fieldSelects, ...htmlSelects].join(',\\n')\n return `db.select({\\n${selects}\\n }).from(${tableVar})`\n}\n\n// ============================================================================\n// List-relationship helpers\n// ============================================================================\n\nexport function findListFieldsWithRelationships(\n fields: SchemaField[]\n): Array<{ field: SchemaField; path: string[] }> {\n const result: Array<{ field: SchemaField; path: string[] }> = []\n for (const field of fields) {\n if (field.type === 'list' && field.fields) {\n const hasRels = field.fields.some((f) => f.type === 'relationship' && f.relationship)\n if (hasRels) {\n result.push({ field, path: [field.name] })\n }\n }\n }\n return result\n}\n\nexport function generatePopulateListRelsFunction(\n queries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n listFieldName: string\n }>,\n Singular: string\n): string {\n const blocks = queries.map((q) => {\n const v = `${q.fieldPath}_${q.relField.name}`\n return ` // ${q.listFieldName} -> ${q.relField.name}\n const ${v}Ids = record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})\n ? (record.${q.listFieldName} as Record<string, unknown>[])\n .map((item) => item.${q.relField.name})\n .filter((id) => id != null && id !== '')\n .map((id) => Number.parseInt(String(id), 10))\n .filter((id) => !Number.isNaN(id))\n : []\n\n const ${v}Results = ${v}Ids.length > 0\n ? await db.select().from(${q.relTable}).where(inArray(${q.relTable}.id, ${v}Ids))\n : []\n\n const ${v}Map = new Map(${v}Results.map((r) => [r.id, r]))\n\n if (record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})) {\n record.${q.listFieldName} = (record.${q.listFieldName} as Record<string, unknown>[]).map((item) => {\n const relId = item.${q.relField.name} ? Number.parseInt(String(item.${q.relField.name}), 10) : null\n return {\n ...item,\n ${q.relField.name}: relId && !Number.isNaN(relId) ? ${v}Map.get(relId) || null : null\n }\n })\n }`\n })\n\n return `\n/**\n * Populate relationship fields inside list (JSONB) fields\n */\nasync function populate${Singular}ListRelationships(record: ${Singular}Data): Promise<${Singular}Data> {\n${blocks.join('\\n\\n')}\n\n return record\n}\n`\n}\n","/**\n * Content generators for individual entity action files.\n * Each function returns the string content for one generated file.\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize } from '../../utils/string.js'\n\n/** Shared context for all entity file generators */\nexport interface EntityCtx {\n singular: string\n plural: string\n Singular: string\n Plural: string\n tableVar: string\n camelSingular: string\n camelPlural: string\n cacheTag: string\n hasRelationships: boolean\n hasM2M: boolean\n hasListRels: boolean\n hasHtmlOutput: boolean\n hasSlug: boolean\n hasDraft: boolean\n hasSearch: boolean\n hasFilters: boolean\n hasAutoSlug: boolean\n searchFields: string[]\n htmlOutputFields: SchemaField[]\n m2mFields: SchemaField[]\n filterableFields: SchemaField[]\n relTableImports: string[]\n listRelTableImports: string[]\n // Pre-computed template fragments\n dataInterface: string\n displayDataInterface: string\n responseInterface: string\n filtersInterface: string\n createInterface: string\n updateInterface: string\n selectClause: string\n listSelectClause: string\n displaySelectClause: string\n filterConditions: string\n searchBlock: string\n resultMapping: string\n listResultMapping: string\n singleRowReturn: string\n displaySingleRowReturn: string\n fieldMeta: string\n createMappings: string\n htmlCreateBlock: string\n htmlCreateMappings: string\n autoSlugCreate: string\n autoSlugUpdate: string\n populateListRelsFn: string\n filters: Array<{ field: string }>\n}\n\n// ============================================================================\n// types.ts\n// ============================================================================\n\nexport function genTypesContent(ctx: EntityCtx): string {\n const parts = [\n ctx.dataInterface,\n ctx.displayDataInterface || null,\n ctx.responseInterface,\n ctx.filtersInterface,\n ctx.createInterface,\n `export interface Create${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n ${ctx.camelSingular}?: ${ctx.Singular}Data\\n}`,\n ctx.updateInterface,\n `export interface Update${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n ${ctx.camelSingular}?: ${ctx.Singular}Data\\n}`,\n `export interface Delete${ctx.Singular}Result {\\n success: boolean\\n error?: string\\n}`,\n `export const CACHE_TAG = '${ctx.cacheTag}'`\n ]\n return parts.filter(Boolean).join('\\n\\n') + '\\n'\n}\n\n// ============================================================================\n// helpers.ts (conditional)\n// ============================================================================\n\nexport function genHelpersContent(ctx: EntityCtx): string | null {\n if (!ctx.hasListRels) return null\n\n const lines: string[] = []\n\n lines.push(`import db from '@cms/db'`)\n const tables = [...new Set(ctx.listRelTableImports)].sort()\n if (tables.length > 0) {\n lines.push(`import { ${tables.join(', ')} } from '@cms/db/schema'`)\n }\n lines.push(`import { inArray } from 'drizzle-orm'`)\n lines.push(`import type { ${ctx.Singular}Data } from './types'`)\n lines.push('')\n\n const exportedFn = ctx.populateListRelsFn\n .replace('async function', 'export async function')\n .trim()\n lines.push(exportedFn)\n lines.push('')\n\n return lines.join('\\n')\n}\n\n// ============================================================================\n// get-{plural}.ts\n// ============================================================================\n\nexport function genGetPluralContent(ctx: EntityCtx): string {\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['asc']\n if (ctx.hasSearch || ctx.filterableFields.length > 1) drizzle.push('and')\n if (ctx.hasSearch) drizzle.push('ilike', 'or')\n if (ctx.filterableFields.some(() => true)) drizzle.push('eq')\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const typeImports = [`${ctx.Plural}Response`, `Get${ctx.Plural}Filters`, `${ctx.Singular}Data`]\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${typeImports.sort().join(', ')} } from './types'${populateImport}\n\nexport async function get${ctx.Plural}(filters?: Get${ctx.Plural}Filters): Promise<${ctx.Plural}Response> {\n try {\n const conditions = []\n${ctx.searchBlock}${ctx.filterConditions}\n\n const query = ${ctx.listSelectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${ctx.tableVar}.sortOrder))\n : query.orderBy(asc(${ctx.tableVar}.sortOrder))\n\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery${ctx.listResultMapping}\n } catch (error) {\n console.error('Error fetching ${ctx.plural}:', error)\n return { ${ctx.camelPlural}: [], total: 0 }\n }\n}\n`\n}\n\n// ============================================================================\n// get-{singular}-by-id.ts\n// ============================================================================\n\nexport function genGetByIdContent(ctx: EntityCtx): string {\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['eq']\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${ctx.Singular}Data } from './types'${populateImport}\n\nexport async function get${ctx.Singular}ById(id: number): Promise<${ctx.Singular}Data | null> {\n try {\n const result = await ${ctx.selectClause}.where(eq(${ctx.tableVar}.id, id)).limit(1)\n if (result.length === 0) return null\n ${ctx.singleRowReturn}\n } catch (error) {\n console.error('Error fetching ${ctx.singular}:', error)\n return null\n }\n}\n`\n}\n\n// ============================================================================\n// get-{singular}-by-slug.ts (conditional)\n// ============================================================================\n\nexport function genGetBySlugContent(ctx: EntityCtx): string | null {\n if (!ctx.hasSlug) return null\n const returnType = ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : `${ctx.Singular}Data`\n const dbImports = [ctx.tableVar, ...ctx.relTableImports].sort()\n const drizzle: string[] = ['eq']\n if (ctx.hasRelationships) drizzle.push('sql')\n const sortedDrizzle = [...new Set(drizzle)].sort()\n\n const typeImport = ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : `${ctx.Singular}Data`\n const extraTypes = ctx.hasListRels && ctx.hasHtmlOutput ? `, ${ctx.Singular}Data` : ''\n const populateImport = ctx.hasListRels\n ? `\\nimport { populate${ctx.Singular}ListRelationships } from './helpers'`\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${dbImports.join(', ')} } from '@cms/db/schema'\nimport { ${sortedDrizzle.join(', ')} } from 'drizzle-orm'\nimport type { ${typeImport}${extraTypes} } from './types'${populateImport}\n\nexport async function get${ctx.Singular}BySlug(slug: string): Promise<${returnType} | null> {\n try {\n const result = await ${ctx.displaySelectClause}.where(eq(${ctx.tableVar}.slug, slug)).limit(1)\n if (result.length === 0) return null\n ${ctx.displaySingleRowReturn}\n } catch (error) {\n console.error('Error fetching ${ctx.singular} by slug:', error)\n return null\n }\n}\n`\n}\n\n// ============================================================================\n// create-{singular}.ts\n// ============================================================================\n\nexport function genCreateContent(ctx: EntityCtx): string {\n const slugImport = ctx.hasAutoSlug ? `\\nimport { slugify } from '@cms/utils/validation'` : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { desc } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Create${ctx.Singular}Input, Create${ctx.Singular}Result, ${ctx.Singular}Data } from './types'${slugImport}\n\nexport async function create${ctx.Singular}(input: Create${ctx.Singular}Input): Promise<Create${ctx.Singular}Result> {\n try {${ctx.autoSlugCreate}\n const maxSortOrderResult = await db\n .select({ maxOrder: ${ctx.tableVar}.sortOrder })\n .from(${ctx.tableVar})\n .orderBy(desc(${ctx.tableVar}.sortOrder))\n .limit(1)\n const nextSortOrder = (maxSortOrderResult[0]?.maxOrder ?? 0) + 1\n${ctx.htmlCreateBlock}\n const result = await db.insert(${ctx.tableVar}).values({\n${ctx.createMappings},${ctx.hasHtmlOutput ? `\\n${ctx.htmlCreateMappings},` : ''}${ctx.hasDraft ? `\\n published: input.published ?? false,` : ''}\n sortOrder: nextSortOrder,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString()\n }).returning()\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${ctx.camelSingular}: result[0] as ${ctx.Singular}Data\n }\n } catch (error) {\n console.error('Error creating ${ctx.singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to create ${ctx.singular}')\n }\n}\n`\n}\n\n// ============================================================================\n// update-{singular}.ts\n// ============================================================================\n\nexport function genUpdateContent(ctx: EntityCtx): string {\n const slugImport = ctx.hasAutoSlug ? `\\nimport { slugify } from '@cms/utils/validation'` : ''\n const htmlUpdateBlock = ctx.hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n ctx.htmlOutputFields.map((f) => ` if (processedData.${f.name} !== undefined) {\\n processedData.${f.name}Html = renderMarkdownSync(String(processedData.${f.name} || ''))\\n }`).join('\\n') + '\\n'\n : ''\n\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Update${ctx.Singular}Input, Update${ctx.Singular}Result, ${ctx.Singular}Data } from './types'${slugImport}\n\nexport async function update${ctx.Singular}(input: Update${ctx.Singular}Input): Promise<Update${ctx.Singular}Result> {\n try {\n const { id, ...updateData } = input\n${ctx.autoSlugUpdate}\n const fieldMeta = [\n ${ctx.fieldMeta}\n ]\n\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(updateData)) {\n if (key === 'published') { processedData[key] = value; continue }\n const field = fieldMeta.find(f => f.name === key)\n if (!field) continue\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (!field.required && ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n${htmlUpdateBlock}\n const result = await db.update(${ctx.tableVar})\n .set({ ...processedData, updatedAt: new Date().toISOString() })\n .where(eq(${ctx.tableVar}.id, id))\n .returning()\n\n if (result.length === 0) throw new Error('${ctx.Singular} not found')\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${ctx.camelSingular}: result[0] as ${ctx.Singular}Data\n }\n } catch (error) {\n console.error('Error updating ${ctx.singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to update ${ctx.singular}')\n }\n}\n`\n}\n\n// ============================================================================\n// delete-{singular}.ts\n// ============================================================================\n\nexport function genDeleteContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Delete${ctx.Singular}Result } from './types'\n\nexport async function delete${ctx.Singular}(id: number): Promise<Delete${ctx.Singular}Result> {\n try {\n await db.delete(${ctx.tableVar}).where(eq(${ctx.tableVar}.id, id))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error deleting ${ctx.singular}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to delete ${ctx.singular}' }\n }\n}\n`\n}\n\n// ============================================================================\n// delete-bulk-{plural}.ts\n// ============================================================================\n\nexport function genDeleteBulkContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { inArray } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Delete${ctx.Singular}Result } from './types'\n\nexport async function deleteBulk${ctx.Plural}(ids: number[]): Promise<Delete${ctx.Singular}Result> {\n try {\n if (ids.length === 0) return { success: false, error: 'No items selected for deletion' }\n await db.delete(${ctx.tableVar}).where(inArray(${ctx.tableVar}.id, ids))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error deleting ${ctx.plural}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to delete ${ctx.plural}' }\n }\n}\n`\n}\n\n// ============================================================================\n// update-{singular}-sort-order.ts\n// ============================================================================\n\nexport function genSortOrderContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { asc, desc, eq, gt, lt } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function update${ctx.Singular}SortOrder(\n id: number,\n direction: 'up' | 'down'\n): Promise<{ success: boolean; error?: string }> {\n try {\n const current = await db.select({ id: ${ctx.tableVar}.id, sortOrder: ${ctx.tableVar}.sortOrder }).from(${ctx.tableVar}).where(eq(${ctx.tableVar}.id, id)).limit(1)\n if (current.length === 0) return { success: false, error: '${ctx.Singular} not found' }\n\n const currentSortOrder = current[0].sortOrder\n const adjacent = await db\n .select({ id: ${ctx.tableVar}.id, sortOrder: ${ctx.tableVar}.sortOrder })\n .from(${ctx.tableVar})\n .where(direction === 'up' ? lt(${ctx.tableVar}.sortOrder, currentSortOrder) : gt(${ctx.tableVar}.sortOrder, currentSortOrder))\n .orderBy(direction === 'up' ? desc(${ctx.tableVar}.sortOrder) : asc(${ctx.tableVar}.sortOrder))\n .limit(1)\n\n if (adjacent.length === 0) return { success: true }\n\n await db.update(${ctx.tableVar}).set({ sortOrder: adjacent[0].sortOrder }).where(eq(${ctx.tableVar}.id, id))\n await db.update(${ctx.tableVar}).set({ sortOrder: currentSortOrder }).where(eq(${ctx.tableVar}.id, adjacent[0].id))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error updating sort order:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to update sort order' }\n }\n}\n`\n}\n\n// ============================================================================\n// bulk-update-{plural}-sort-order.ts\n// ============================================================================\n\nexport function genBulkSortOrderContent(ctx: EntityCtx): string {\n return `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function bulkUpdate${ctx.Plural}SortOrder(\n updates: Array<{ id: number; sortOrder: number }>\n): Promise<{ success: boolean; error?: string }> {\n try {\n if (updates.length === 0) return { success: true }\n await Promise.all(updates.map((u) => db.update(${ctx.tableVar}).set({ sortOrder: u.sortOrder }).where(eq(${ctx.tableVar}.id, u.id))))\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error bulk updating sort order:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to bulk update sort order' }\n }\n}\n`\n}\n\n// ============================================================================\n// M2M files: get-{rel}-for-{singular}.ts and set-{rel}-for-{singular}.ts\n// ============================================================================\n\nexport function genM2MFiles(ctx: EntityCtx): Array<{ name: string; content: string }> {\n const files: Array<{ name: string; content: string }> = []\n\n for (const f of ctx.m2mFields) {\n const rel = f.relationship || ''\n const RelPascal = toPascalCase(rel)\n const relSingular = singularize(rel)\n const junctionVar = toCamelCase(`${ctx.singular}${RelPascal}`)\n const entityIdCol = `${ctx.singular}Id`\n const relIdCol = `${relSingular}Id`\n const kebabRel = rel.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n\n // get file\n files.push({\n name: `get-${kebabRel}-for-${ctx.singular}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${junctionVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\n\nexport async function get${RelPascal}For${ctx.Singular}(${ctx.singular}Id: number): Promise<number[]> {\n try {\n const results = await db.select({ ${relIdCol}: ${junctionVar}.${relIdCol} }).from(${junctionVar}).where(eq(${junctionVar}.${entityIdCol}, ${ctx.singular}Id))\n return results.map(r => r.${relIdCol})\n } catch (error) {\n console.error('Error fetching ${rel} for ${ctx.singular}:', error)\n return []\n }\n}\n`\n })\n\n // set file\n files.push({\n name: `set-${kebabRel}-for-${ctx.singular}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${junctionVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\n\nexport async function set${RelPascal}For${ctx.Singular}(${ctx.singular}Id: number, ${rel}Ids: number[]): Promise<{ success: boolean; error?: string }> {\n try {\n await db.delete(${junctionVar}).where(eq(${junctionVar}.${entityIdCol}, ${ctx.singular}Id))\n if (${rel}Ids.length > 0) {\n await db.insert(${junctionVar}).values(${rel}Ids.map(${relSingular}Id => ({ ${entityIdCol}: ${ctx.singular}Id, ${relIdCol}: ${relSingular}Id })))\n }\n revalidateTag(CACHE_TAG)\n return { success: true }\n } catch (error) {\n console.error('Error setting ${rel} for ${ctx.singular}:', error)\n return { success: false, error: error instanceof Error ? error.message : 'Failed to set ${rel}' }\n }\n}\n`\n })\n }\n\n return files\n}\n\n// ============================================================================\n// get-distinct-{plural}-{field}.ts files\n// ============================================================================\n\nexport function genDistinctFiles(ctx: EntityCtx): Array<{ name: string; content: string }> {\n if (!ctx.hasFilters) return []\n\n return ctx.filters.map((filter) => {\n const fieldPascal = toPascalCase(filter.field)\n const kebabField = filter.field.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n const kebabPlural = ctx.plural.replace(/([A-Z])/g, '-$1').toLowerCase().replace(/^-/, '')\n\n return {\n name: `get-distinct-${kebabPlural}-${kebabField}.ts`,\n content: `'use server'\n\nimport db from '@cms/db'\nimport { ${ctx.tableVar} } from '@cms/db/schema'\nimport { asc, isNotNull } from 'drizzle-orm'\n\nexport async function getDistinct${ctx.Plural}${fieldPascal}(): Promise<string[]> {\n try {\n const results = await db\n .selectDistinct({ value: ${ctx.tableVar}.${filter.field} })\n .from(${ctx.tableVar})\n .where(isNotNull(${ctx.tableVar}.${filter.field}))\n .orderBy(asc(${ctx.tableVar}.${filter.field}))\n return results.map((r) => String(r.value)).filter(Boolean)\n } catch (error) {\n console.error('Error fetching distinct ${ctx.plural} ${filter.field}:', error)\n return []\n }\n}\n`\n }\n })\n}\n\n// ============================================================================\n// index.ts (barrel)\n// ============================================================================\n\nexport function genBarrelContent(\n files: Array<{ name: string; content: string }>,\n ctx: EntityCtx\n): string {\n const lines: string[] = []\n\n // Re-export types\n const typeNames: string[] = [\n `${ctx.Singular}Data`,\n ctx.hasHtmlOutput ? `${ctx.Singular}DisplayData` : null,\n `${ctx.Plural}Response`,\n `Get${ctx.Plural}Filters`,\n `Create${ctx.Singular}Input`,\n `Create${ctx.Singular}Result`,\n `Update${ctx.Singular}Input`,\n `Update${ctx.Singular}Result`,\n `Delete${ctx.Singular}Result`,\n ].filter(Boolean) as string[]\n lines.push(`export type { ${typeNames.join(', ')} } from './types'`)\n lines.push('')\n\n // Re-export action functions from each file (skip types.ts, helpers.ts, index.ts)\n for (const file of files) {\n if (file.name === 'types.ts' || file.name === 'helpers.ts') continue\n // Extract exported function names from the content\n const exportMatches = file.content.matchAll(/export async function (\\w+)/g)\n const fnNames = [...exportMatches].map((m) => m[1])\n if (fnNames.length > 0) {\n const modulePath = './' + file.name.replace(/\\.ts$/, '')\n lines.push(`export { ${fnNames.join(', ')} } from '${modulePath}'`)\n }\n }\n\n lines.push('')\n return lines.join('\\n')\n}\n","/**\n * Generator 2b: Server actions for single (singleton) schemas\n * Split into individual files: types.ts, get-{singular}.ts, upsert-{singular}.ts, index.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields } from '../../core/field-helpers/index.js'\nimport type { Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, toKebabCase, quotePropertyName } from '../../utils/string.js'\nimport type { ActionsGeneratorResult } from './action-helpers.js'\nimport { generateFieldMapping, getFieldType } from './action-helpers.js'\n\n/**\n * Generate server actions for a single (singleton) schema, split into individual files.\n */\nexport function generateSingleActions(\n schema: Schema,\n cwd: string,\n actionsDir: string,\n options: { force?: boolean } = {}\n): ActionsGeneratorResult {\n const absActionsDir = path.join(cwd, actionsDir)\n const dirPath = path.join(absActionsDir, schema.name)\n const oldFilePath = path.join(absActionsDir, `${schema.name}.ts`)\n\n if (!options.force && (fs.existsSync(dirPath) || fs.existsSync(oldFilePath))) {\n return { files: [] }\n }\n\n if (options.force) {\n if (fs.existsSync(oldFilePath)) fs.unlinkSync(oldFilePath)\n if (fs.existsSync(dirPath)) fs.rmSync(dirPath, { recursive: true })\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const tableVar = toCamelCase(schema.name)\n const camelSingular = toCamelCase(singular)\n const kebabSingular = toKebabCase(singular)\n\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true) && !isLayoutField(f.type)\n )\n\n const htmlOutputFields = dbFields.filter(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n const hasHtmlOutput = htmlOutputFields.length > 0\n\n const allDbFields = [...dbFields]\n if (!dbFields.some((f) => f.name === 'createdAt')) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!dbFields.some((f) => f.name === 'updatedAt')) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n\n const upsertFields = dbFields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n\n // --- Build types ---\n const dataFields = allDbFields\n .map(\n (f) =>\n ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output')}${f.required ? '' : ' | null'}`\n )\n .join('\\n')\n const htmlFieldTypes = htmlOutputFields.map((f) => ` ${f.name}Html: string`).join('\\n')\n\n const upsertInterfaceFields = upsertFields\n .map(\n (f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`\n )\n .join('\\n')\n\n const fieldMeta = upsertFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const upsertMappings = upsertFields\n .map((f) => ` ${f.name}: ${generateFieldMapping(f)}`)\n .join(',\\n')\n\n const cacheTag = `${schema.name}:all`\n\n // --- types.ts ---\n const typesContent = [\n `export interface ${Singular}Data {\\n${dataFields}${htmlFieldTypes ? `\\n${htmlFieldTypes}` : ''}\\n}`,\n `export interface Upsert${Singular}Input {\\n${upsertInterfaceFields}\\n}`,\n `export interface Upsert${Singular}Result {\\n success: boolean\\n error?: string\\n ${camelSingular}?: ${Singular}Data\\n}`,\n `export const CACHE_TAG = '${cacheTag}'`\n ].join('\\n\\n') + '\\n'\n\n // --- get-{singular}.ts ---\n const getContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableVar} } from '@cms/db/schema'\nimport { eq } from 'drizzle-orm'\nimport type { ${Singular}Data } from './types'\n\nexport async function get${Singular}(): Promise<${Singular}Data | null> {\n try {\n const result = await db.select().from(${tableVar}).where(eq(${tableVar}.id, 1)).limit(1)\n if (result.length === 0) return null\n return result[0] as ${Singular}Data\n } catch (error) {\n console.error('Error fetching ${singular}:', error)\n return null\n }\n}\n`\n\n // --- upsert-{singular}.ts ---\n const htmlUpsertBlock = hasHtmlOutput\n ? `\\n const { renderMarkdownSync } = await import('@cms/lib/markdown/render')\\n` +\n htmlOutputFields.map((f) => ` if (processedData.${f.name} !== undefined) {\\n processedData.${f.name}Html = renderMarkdownSync(String(processedData.${f.name} || ''))\\n }`).join('\\n') + '\\n' +\n htmlOutputFields.map((f) => ` const ${f.name}Html = renderMarkdownSync(input.${f.name} || '')`).join('\\n') + '\\n'\n : ''\n const htmlUpsertMappings = hasHtmlOutput\n ? '\\n' + htmlOutputFields.map((f) => ` ${f.name}Html`).join(',\\n') + ','\n : ''\n\n const upsertContent = `'use server'\n\nimport db from '@cms/db'\nimport { ${tableVar} } from '@cms/db/schema'\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAG } from './types'\nimport type { Upsert${Singular}Input, Upsert${Singular}Result, ${Singular}Data } from './types'\n\nexport async function upsert${Singular}(input: Upsert${Singular}Input): Promise<Upsert${Singular}Result> {\n try {\n const fieldMeta = [\n ${fieldMeta}\n ]\n\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(input)) {\n const field = fieldMeta.find(f => f.name === key)\n if (!field) continue\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (!field.required && ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n${htmlUpsertBlock}\n const now = new Date().toISOString()\n\n const result = await db\n .insert(${tableVar})\n .values({\n id: 1,\n ...processedData,\n createdAt: now,\n updatedAt: now\n })\n .onConflictDoUpdate({\n target: ${tableVar}.id,\n set: { ...processedData, updatedAt: now }\n })\n .returning()\n\n revalidateTag(CACHE_TAG)\n\n return {\n success: true,\n ${camelSingular}: result[0] as ${Singular}Data\n }\n } catch (error) {\n console.error('Error upserting ${singular}:', error)\n throw new Error(error instanceof Error ? error.message : 'Failed to save ${singular}')\n }\n}\n`\n\n // --- index.ts (barrel) ---\n const barrelContent = `export type { ${Singular}Data, Upsert${Singular}Input, Upsert${Singular}Result } from './types'\nexport { get${Singular} } from './get-${kebabSingular}'\nexport { upsert${Singular} } from './upsert-${kebabSingular}'\n`\n\n // Write all files\n const files = [\n { name: 'types.ts', content: typesContent },\n { name: `get-${kebabSingular}.ts`, content: getContent },\n { name: `upsert-${kebabSingular}.ts`, content: upsertContent },\n { name: 'index.ts', content: barrelContent }\n ]\n\n fs.mkdirSync(dirPath, { recursive: true })\n for (const file of files) {\n fs.writeFileSync(path.join(dirPath, file.name), file.content, 'utf-8')\n }\n\n return { files: files.map((f) => path.join(actionsDir, schema.name, f.name)) }\n}\n","/**\n * Generator 12: Cache module — cms/lib/cache/\n * Generates tags, cached queries, and revalidation helpers for all schemas\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toScreamingSnake } from '../utils/string.js'\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\ninterface NestedLookupConfig {\n name: string\n pascalName: string\n camelName: string\n screamingSnake: string\n slugField: string\n}\n\ninterface CacheConfig {\n name: string\n singularName: string\n pluralName: string\n pascalSingular: string\n pascalPlural: string\n screamingSnake: string\n hasSlug: boolean\n isSingle: boolean\n nestedLookups: NestedLookupConfig[]\n}\n\n// ============================================================================\n// Schema Loading\n// ============================================================================\n\nfunction loadAllSchemas(cwd: string, schemasDir: string): Schema[] {\n const dir = path.join(cwd, schemasDir)\n if (!fs.existsSync(dir)) return []\n\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'))\n const seen = new Map<string, Schema>()\n\n for (const file of files) {\n if (file === 'schema.json') continue // skip metaschema\n const content = fs.readFileSync(path.join(dir, file), 'utf-8')\n const schema = JSON.parse(content) as Schema\n if (!schema.name) continue // skip non-entity JSON files\n seen.set(schema.name, schema)\n }\n\n return Array.from(seen.values())\n}\n\nfunction buildCacheConfig(schema: Schema): CacheConfig {\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const dbFields = flattenFields(schema.fields)\n const hasSlug = dbFields.some((f) => f.name === 'slug')\n\n const nestedLookups: NestedLookupConfig[] = (schema.nestedSlugLookups || []).map((lookup) => ({\n name: lookup.name,\n pascalName: toPascalCase(lookup.name),\n camelName: toCamelCase(lookup.name),\n screamingSnake: toScreamingSnake(lookup.name),\n slugField: lookup.slugField || 'slug'\n }))\n\n return {\n name: schema.name,\n singularName,\n pluralName,\n pascalSingular: toPascalCase(singularName),\n pascalPlural: toPascalCase(pluralName),\n screamingSnake: toScreamingSnake(pluralName),\n hasSlug,\n isSingle: schema.type === 'single',\n nestedLookups\n }\n}\n\n// ============================================================================\n// File Generators\n// ============================================================================\n\nfunction generateTags(configs: CacheConfig[]): string {\n const entries: string[] = []\n\n for (const c of configs) {\n entries.push(` ${c.screamingSnake}_ALL: '${c.pluralName}:all'`)\n\n if (c.isSingle) continue // single schemas only need the ALL tag\n\n if (c.hasSlug) {\n entries.push(\n ` ${c.screamingSnake}_BY_SLUG: (slug: string) => \\`${c.pluralName}:slug:\\${slug}\\``\n )\n }\n\n for (const n of c.nestedLookups) {\n entries.push(\n ` ${c.screamingSnake}_${n.screamingSnake}_BY_SLUG: (${c.singularName}Slug: string, ${n.camelName}Slug: string) => \\`${c.pluralName}:\\${${c.singularName}Slug}:${n.name}:\\${${n.camelName}Slug}\\``\n )\n }\n }\n\n entries.sort()\n\n return `/**\n * Cache tag constants for Next.js 'use cache' invalidation\n * AUTO-GENERATED — do not edit directly\n */\n\nexport const CACHE_TAGS = {\n${entries.join(',\\n')}\n} as const\n`\n}\n\nfunction generateCachedQueries(configs: CacheConfig[]): string {\n const actionImports: string[] = []\n const typeImportsBySchema = new Map<string, string[]>()\n const fns: string[] = []\n\n for (const c of configs) {\n if (c.isSingle) {\n // Single schema: getCachedXxx() with no filters\n actionImports.push(`get${c.pascalSingular}`)\n\n fns.push(`\nexport const getCached${c.pascalSingular} = async () => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalSingular}()\n}`)\n continue\n }\n\n // Entity schema: getCachedXxxPlural(filters) + slug lookups\n actionImports.push(`get${c.pascalPlural}`)\n const types = typeImportsBySchema.get(c.name) || []\n types.push(`Get${c.pascalPlural}Filters`)\n typeImportsBySchema.set(c.name, types)\n\n if (c.hasSlug) actionImports.push(`get${c.pascalSingular}BySlug`)\n for (const n of c.nestedLookups) actionImports.push(`get${n.pascalName}BySlug`)\n\n fns.push(`\nexport const getCached${c.pascalPlural} = async (filters?: Get${c.pascalPlural}Filters) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalPlural}(filters)\n}`)\n\n if (c.hasSlug) {\n fns.push(`\nexport const getCached${c.pascalSingular}BySlug = async (slug: string) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_BY_SLUG(slug))\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${c.pascalSingular}BySlug(slug)\n}`)\n }\n\n for (const n of c.nestedLookups) {\n fns.push(`\nexport const getCached${n.pascalName}BySlug = async (${c.singularName}Slug: string, ${n.camelName}Slug: string) => {\n cacheLife('max')\n cacheTag(CACHE_TAGS.${c.screamingSnake}_${n.screamingSnake}_BY_SLUG(${c.singularName}Slug, ${n.camelName}Slug))\n cacheTag(CACHE_TAGS.${c.screamingSnake}_ALL)\n return get${n.pascalName}BySlug(${c.singularName}Slug, ${n.camelName}Slug)\n}`)\n }\n }\n\n actionImports.sort()\n\n const typeImportStr =\n typeImportsBySchema.size > 0\n ? `${Array.from(typeImportsBySchema.entries())\n .map(([schemaName, types]) => `import type { ${types.sort().join(', ')} } from '@cms/actions/${schemaName}'`)\n .join('\\n')}\\n`\n : ''\n\n // Group action imports by schema\n const actionsBySchema = new Map<string, string[]>()\n for (const c of configs) {\n if (c.isSingle) {\n actionsBySchema.set(c.name, [`get${c.pascalSingular}`])\n continue\n }\n const names: string[] = [`get${c.pascalPlural}`]\n if (c.hasSlug) names.push(`get${c.pascalSingular}BySlug`)\n for (const n of c.nestedLookups) names.push(`get${n.pascalName}BySlug`)\n actionsBySchema.set(c.name, names)\n }\n\n const actionImportLines = Array.from(actionsBySchema.entries())\n .map(([name, fns]) => `import { ${fns.join(', ')} } from '@cms/actions/${name}'`)\n .join('\\n')\n\n return `'use cache'\n\n/**\n * Cached query functions for Next.js 'use cache'\n * AUTO-GENERATED — do not edit directly\n */\n\nimport { cacheLife, cacheTag } from 'next/cache'\n${typeImportStr}${actionImportLines}\nimport { CACHE_TAGS } from './tags'\n${fns.join('\\n')}\n`\n}\n\nfunction generateRevalidate(configs: CacheConfig[]): string {\n const fns: string[] = []\n\n for (const c of configs) {\n if (c.isSingle) {\n fns.push(`\nexport const revalidate${c.pascalSingular} = async () => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n continue\n }\n\n fns.push(`\nexport const revalidate${c.pascalPlural} = async () => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n\n if (c.hasSlug) {\n fns.push(`\nexport const revalidate${c.pascalSingular}BySlug = async (slug: string) => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_BY_SLUG(slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n\n for (const n of c.nestedLookups) {\n fns.push(`\nexport const revalidate${n.pascalName}BySlug = async (${c.singularName}Slug: string, ${n.camelName}Slug: string) => {\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_${n.screamingSnake}_BY_SLUG(${c.singularName}Slug, ${n.camelName}Slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${c.screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n }\n\n return `'use server'\n\n/**\n * Revalidation helpers for Next.js cache invalidation\n * AUTO-GENERATED — do not edit directly\n */\n\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAGS } from './tags'\n\nconst REVALIDATION_STRATEGY = 'max' as const\n${fns.join('\\n')}\n`\n}\n\nfunction generateIndex(): string {\n return `/**\n * Cache module exports\n * AUTO-GENERATED — do not edit directly\n */\n\nexport * from './tags'\nexport * from './cached-queries'\nexport * from './cached-queries-custom'\nexport * from './revalidate'\n`\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface CacheGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate all cache files based on all schemas in cms/schemas/\n */\nexport function generateCache(\n _schema: Schema,\n cwd: string,\n cmsDir: string,\n _options: GeneratorOptions = {}\n): CacheGeneratorResult {\n const cacheDir = path.join(cwd, cmsDir, 'lib', 'cache')\n const schemasDir = path.join(cmsDir, 'schemas')\n\n // Load all schemas and build configs (skip form schemas — they have no cacheable queries)\n const isFormSchema = (s: Schema) => 'submitButtonText' in s || 'steps' in s\n const schemas = loadAllSchemas(cwd, schemasDir).filter((s) => s.fields && !isFormSchema(s))\n const configs = schemas.map(buildCacheConfig).sort((a, b) => a.name.localeCompare(b.name))\n\n if (!fs.existsSync(cacheDir)) {\n fs.mkdirSync(cacheDir, { recursive: true })\n }\n\n const files: string[] = []\n\n // tags.ts\n fs.writeFileSync(path.join(cacheDir, 'tags.ts'), generateTags(configs), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'tags.ts'))\n\n // cached-queries.ts\n fs.writeFileSync(\n path.join(cacheDir, 'cached-queries.ts'),\n generateCachedQueries(configs),\n 'utf-8'\n )\n files.push(path.join(cmsDir, 'lib', 'cache', 'cached-queries.ts'))\n\n // revalidate.ts\n fs.writeFileSync(path.join(cacheDir, 'revalidate.ts'), generateRevalidate(configs), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'revalidate.ts'))\n\n // cached-queries-custom.ts (user-maintained, scaffold only if missing)\n const customQueriesPath = path.join(cacheDir, 'cached-queries-custom.ts')\n if (!fs.existsSync(customQueriesPath)) {\n fs.writeFileSync(\n customQueriesPath,\n `/**\\n * Custom cached query functions (not auto-generated)\\n * Add your custom cached queries here.\\n */\\n\\nexport {}\\n`,\n 'utf-8'\n )\n files.push(path.join(cmsDir, 'lib', 'cache', 'cached-queries-custom.ts'))\n }\n\n // index.ts\n fs.writeFileSync(path.join(cacheDir, 'index.ts'), generateIndex(), 'utf-8')\n files.push(path.join(cmsDir, 'lib', 'cache', 'index.ts'))\n\n return { files }\n}\n","/**\n * Generator 4: Column definitions — (authenticated)/<n>/columns.tsx\n * Generates TanStack Table column definitions for entity list views\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../../types.js'\nimport { toPascalCase, singularize, pluralize } from '../../utils/string.js'\nimport {\n generateColumnDef,\n generateFirstColumnDef,\n generateTitleFallback,\n isSortableColumn\n} from './column-defs.js'\nimport {\n generateDeleteActionTemplate,\n generateReorderButtonsTemplate,\n generateTruncateHelper\n} from './column-actions.js'\nimport { createCustomCellComponent } from './custom-cell.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface ColumnsGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate column definitions for entity list view\n */\nexport function generateColumns(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): ColumnsGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const columnsFilePath = path.join(entityDir, 'columns.tsx')\n\n if (fs.existsSync(columnsFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n\n const flatFields = flattenFields(schema.fields || [])\n const titleFallback = generateTitleFallback(flatFields)\n\n // --- Determine needed imports ---\n let needsArrowUpDown = false\n let needsBadge = false\n let needsButton = true // Always for actions column\n let needsAvatar = false\n let needsTruncate = false\n let needsReactQueryClient = false\n let needsToast = false\n let needsAlertDialog = false\n let needsTrash = false\n\n for (const column of schema.columns) {\n if (isSortableColumn(column)) {\n needsArrowUpDown = true\n needsButton = true\n }\n if (column.type === 'badge' || column.type === 'boolean') needsBadge = true\n if (column.type === 'image' || column.type === 'avatar') needsAvatar = true\n if (column.type === 'link') needsTruncate = true\n }\n\n const hasEdit = schema.actions?.edit ?? false\n const hasDelete = schema.actions?.delete ?? false\n if (hasDelete) {\n needsTrash = true\n needsAlertDialog = true\n needsReactQueryClient = true\n needsToast = true\n }\n\n // --- Build lucide icons ---\n const lucideIcons: string[] = []\n if (needsArrowUpDown) lucideIcons.push('ArrowUpDown')\n lucideIcons.push('ChevronDown', 'ChevronUp', 'Edit')\n if (needsTrash) lucideIcons.push('Trash')\n\n // --- Build UI component imports (individual per-component) ---\n const uiImports: string[] = []\n if (needsButton) uiImports.push(\"import { Button } from '@cms/components/ui/button'\")\n if (needsBadge) uiImports.push(\"import { Badge } from '@cms/components/ui/badge'\")\n uiImports.push(\"import { Checkbox } from '@cms/components/ui/checkbox'\")\n if (needsAvatar) {\n uiImports.push(\n \"import { Avatar, AvatarImage, AvatarFallback } from '@cms/components/ui/avatar'\"\n )\n }\n if (needsAlertDialog) {\n uiImports.push(`import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger\n} from '@cms/components/ui/alert-dialog'`)\n }\n\n // --- Custom component imports ---\n const customImports: string[] = []\n for (const column of schema.columns) {\n if (column.type === 'custom' && column.component) {\n customImports.push(`import { ${column.component} } from './cells/${column.component}'`)\n createCustomCellComponent(schema, column.component, cwd, pagesDir, options)\n }\n }\n\n // --- Action imports ---\n const actionImports: string[] = []\n if (hasDelete) actionImports.push(`delete${Singular}`)\n\n // --- Generate columns ---\n const firstColumn = schema.columns[0]\n const restColumns = schema.columns.slice(1)\n\n const firstColDef = generateFirstColumnDef(firstColumn, flatFields, schema.name)\n const restColDefs = restColumns.map((col) => generateColumnDef(col, flatFields)).join(',\\n')\n\n // --- Delete handler ---\n const deleteHandler = hasDelete\n ? generateDeleteActionTemplate({ Singular, singular, plural })\n : ''\n\n // --- Reorder handler ---\n const reorderHandler = generateReorderButtonsTemplate()\n\n // --- Reorder column ---\n const reorderColumn = ` {\n id: 'reorder',\n header: () => <span className=\"sr-only\">Reorder</span>,\n cell: ({ row, table }) => {\n const reorderMode = table.options.meta?.reorderMode\n const onMoveRow = table.options.meta?.onMoveRow\n\n if (!reorderMode) return null\n\n const allRows = table.getRowModel().rows\n const currentIndex = allRows.findIndex(r => r.id === row.id)\n const isFirst = currentIndex === 0\n const isLast = currentIndex === allRows.length - 1\n\n return (\n <ReorderButtons\n id={row.original.id as number}\n isFirst={isFirst}\n isLast={isLast}\n onMoveRow={onMoveRow}\n />\n )\n },\n enableSorting: false,\n enableHiding: false,\n size: 80\n }`\n\n // --- Edit button ---\n let editButton = ''\n if (hasEdit) {\n editButton = ` <Button variant=\"outline\" className=\"size-8\" asChild>\n <Link href={\\`/cms/${schema.name}/\\${row.original.id}/edit\\`}>\n <Edit className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Edit ${singular} {${titleFallback}}</span>\n </Link>\n </Button>`\n }\n\n // --- Actions column ---\n const actionsColumn = ` {\n id: 'actions',\n header: () => <div className=\"text-right\">Actions</div>,\n cell: ({ row }) => (\n <div className=\"flex justify-end items-center gap-2\">\n${editButton}\n${hasDelete ? ' <DeleteAction id={row.original.id as number} />' : ''}\n </div>\n )\n }`\n\n // --- Truncate helper ---\n const truncateHelper = needsTruncate\n ? generateTruncateHelper()\n : ''\n\n // --- Assemble file ---\n const content = `'use client'\n\nimport type { ColumnDef } from '@tanstack/react-table'\n${needsReactQueryClient ? \"import { useQueryClient } from '@tanstack/react-query'\" : ''}\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'\nimport Link from 'next/link'\nimport * as React from 'react'\n${needsToast ? \"import { toast } from 'sonner'\" : ''}\n${uiImports.join('\\n')}\n${actionImports.length > 0 ? `import { ${actionImports.join(', ')} } from '@cms/actions/${schema.name}'` : ''}\nimport type { ${Singular}Data } from '@cms/actions/${schema.name}'\n${customImports.join('\\n')}\n${truncateHelper}${deleteHandler}${reorderHandler}\nexport const columns: ColumnDef<${Singular}Data>[] = [\n${reorderColumn},\n${firstColDef}${restColDefs ? `,\\n${restColDefs}` : ''},\n${actionsColumn}\n]\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(columnsFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'columns.tsx')]\n }\n}\n","/**\n * Column definition generators for TanStack Table columns\n */\n\nimport type { SchemaColumn, SchemaField } from '../../types.js'\n\n// ============================================================================\n// Column Helpers\n// ============================================================================\n\nexport function isSortableColumn(column: SchemaColumn): boolean {\n if (typeof column.sortable === 'boolean') return column.sortable\n const nonSortableTypes = ['image', 'avatar', 'link', 'custom']\n return !nonSortableTypes.includes(column.type)\n}\n\nexport function generateTitleFallback(fields: SchemaField[]): string {\n const fieldNames = new Set(fields.map((f) => f.name))\n const fallbacks: string[] = []\n if (fieldNames.has('title')) fallbacks.push('row.original.title')\n if (fieldNames.has('name')) fallbacks.push('row.original.name')\n fallbacks.push('row.original.id')\n fallbacks.push(\"''\")\n return fallbacks.join(' || ')\n}\n\n// ============================================================================\n// Cell Renderers\n// ============================================================================\n\nexport function generateColumnDef(column: SchemaColumn, fields: SchemaField[]): string {\n const sortable = isSortableColumn(column)\n const headerDef = sortable\n ? `header: ({ column }) => {\n const sortDirection = column.getIsSorted()\n const sortLabel = sortDirection === 'asc'\n ? 'sorted ascending'\n : sortDirection === 'desc'\n ? 'sorted descending'\n : 'not sorted'\n\n return (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n aria-label={\\`Sort by ${column.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${column.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n }`\n : `header: '${column.header}'`\n\n const titleFallback = generateTitleFallback(fields)\n let cellDef = ''\n\n switch (column.type) {\n case 'image':\n cellDef = `cell: ({ row }) => {\n const imageUrl = row.getValue('${column.accessorKey}') ?? ''\n const title = ${titleFallback}\n return (\n <Avatar className=\"size-10 border\">\n <AvatarImage\n src={imageUrl}\n alt={title ? \\`${column.header} image for \\${title}\\` : '${column.header} image'}\n />\n <AvatarFallback>\n {String(title || imageUrl).substring(0, 2).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n )\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return (\n <Badge variant=\"outline\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </Badge>\n )\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = new Date(row.getValue('${column.accessorKey}'))\n return (\n <div className=\"text-sm\">\n {date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric'\n })}\n </div>\n )\n }`\n break\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${column.accessorKey}') as string\n return <div className=\"text-sm font-medium\">{email}</div>\n }`\n break\n case 'number':\n if (column.format === 'currency') {\n cellDef = `cell: ({ row }) => {\n const amount = row.getValue('${column.accessorKey}') as number\n return (\n <div className=\"text-sm font-medium\">\n {new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount)}\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as number\n return <div className=\"text-sm\">{value}</div>\n }`\n }\n break\n case 'boolean':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as boolean\n return (\n <Badge variant={value ? 'outline' : 'secondary'}>\n {value ? 'Yes' : 'No'}\n </Badge>\n )\n }`\n break\n case 'link':\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}') as string\n if (!value) return <div className=\"text-muted-foreground\">\\u2014</div>\n return (\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300\"\n title={value}\n >\n {truncateStr(value, 50)}\n </a>\n )\n }`\n break\n case 'custom':\n if (column.component) {\n cellDef = `cell: ({ row }) => {\n return <${column.component} data={row.original} />\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return <div>{value === null || value === undefined ? 'Unavailable' : String(value)}</div>\n }`\n }\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.getValue('${column.accessorKey}')\n return <div>{value === null || value === undefined ? 'Unavailable' : String(value)}</div>\n }`\n break\n }\n\n return ` {\n accessorKey: '${column.accessorKey}',\n ${headerDef},\n ${cellDef}\n }`\n}\n\nexport function generateFirstColumnDef(\n column: SchemaColumn,\n fields: SchemaField[],\n schemaName: string\n): string {\n const sortable = isSortableColumn(column)\n const headerDef = sortable\n ? `header: ({ table, column }) => {\n const sortDirection = column.getIsSorted()\n const sortLabel = sortDirection === 'asc'\n ? 'sorted ascending'\n : sortDirection === 'desc'\n ? 'sorted descending'\n : 'not sorted'\n\n return (\n <div className=\"flex items-center gap-4\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n aria-label={\\`Sort by ${column.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${column.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n </div>\n )\n }`\n : `header: ({ table }) => (\n <div className=\"flex items-center gap-4\">\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n <span>${column.header}</span>\n </div>\n )`\n\n const titleFallback = generateTitleFallback(fields)\n const linkBase = `/cms/${schemaName}`\n let cellDef = ''\n\n switch (column.type) {\n case 'image':\n cellDef = `cell: ({ row }) => {\n const imageUrl = row.original.${column.accessorKey} as string\n const title = ${titleFallback}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Avatar className=\"size-10 border\">\n <AvatarImage\n src={imageUrl}\n alt={title ? \\`${column.header} image for \\${title}\\` : '${column.header} image'}\n />\n <AvatarFallback>\n {String(title || imageUrl).substring(0, 2).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'badge':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Badge variant=\"outline\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </Badge>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'date':\n cellDef = `cell: ({ row }) => {\n const date = new Date(row.original.${column.accessorKey})\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm\">\n {date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric'\n })}\n </div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.original.${column.accessorKey} as string\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"text-sm font-medium truncate\">{email}</span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'number':\n if (column.format === 'currency') {\n cellDef = `cell: ({ row }) => {\n const amount = row.original.${column.accessorKey} as number\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm font-medium\">\n {new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD'\n }).format(amount)}\n </div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as number\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full\"\n >\n <div className=\"text-sm\">{value}</div>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n }\n break\n case 'boolean':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as boolean\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <Badge variant={value ? 'outline' : 'secondary'}>\n {value ? 'Yes' : 'No'}\n </Badge>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n case 'custom':\n if (column.component) {\n cellDef = `cell: ({ row }) => {\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity\">\n <${column.component} data={row.original} />\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n } else {\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"truncate\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n }\n break\n case 'link':\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey} as string\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link href={\\`${linkBase}/\\${row.original.id}/edit\\`} className=\"flex items-center gap-2 hover:opacity-80 transition-opacity max-w-[250px]\">\n {value ? (\n <a\n href={value}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300 truncate block\"\n title={value}\n onClick={(e) => e.stopPropagation()}\n >\n {truncateStr(value, 50)}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">\\u2014</span>\n )}\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n default:\n cellDef = `cell: ({ row }) => {\n const value = row.original.${column.accessorKey}\n return (\n <div className=\"flex items-center gap-4 h-full group\">\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n <Link\n href={\\`${linkBase}/\\${row.original.id}/edit\\`}\n className=\"dark:hover:text-blue-500 hover:text-blue-600 transition-colors flex items-center gap-2 h-full w-full max-w-[300px] py-3\"\n >\n <span className=\"truncate\">\n {value === null || value === undefined ? 'Unavailable' : String(value)}\n </span>\n <Edit\n className=\"size-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0\"\n strokeWidth={2}\n />\n </Link>\n </div>\n )\n }`\n break\n }\n\n return ` {\n id: 'select',\n accessorKey: '${column.accessorKey}',\n ${headerDef},\n ${cellDef},\n enableSorting: ${sortable ? 'true' : 'false'},\n enableHiding: false\n }`\n}\n","/**\n * Template strings for inline column action components:\n * DeleteAction, ReorderButtons, and truncateStr helper\n */\n\n// ============================================================================\n// Delete Action Component Template\n// ============================================================================\n\nexport function generateDeleteActionTemplate(params: {\n Singular: string\n singular: string\n plural: string\n}): string {\n const { Singular, singular, plural } = params\n\n return `\nfunction DeleteAction({ id }: { id: number }) {\n const [open, setOpen] = React.useState(false)\n const [isPending, startTransition] = React.useTransition()\n const queryClient = useQueryClient()\n\n const handleDelete = () => {\n startTransition(async () => {\n try {\n const result = await delete${Singular}(id)\n\n if (result.success) {\n toast.success('${Singular} deleted successfully')\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${singular}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n\n return (\n <AlertDialog open={open} onOpenChange={setOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" className=\"size-8\" aria-label={\\`Delete ${singular} \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete ${singular}</span>\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete this ${singular}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault()\n handleDelete()\n }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n}\n`\n}\n\n// ============================================================================\n// Reorder Buttons Component Template\n// ============================================================================\n\nexport function generateReorderButtonsTemplate(): string {\n return `\nfunction ReorderButtons({\n id,\n isFirst,\n isLast,\n onMoveRow\n}: {\n id: number\n isFirst: boolean\n isLast: boolean\n onMoveRow?: (id: number, direction: 'up' | 'down') => void\n}) {\n if (!onMoveRow) return null\n\n return (\n <div className=\"flex items-center gap-0.5\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => onMoveRow(id, 'up')}\n disabled={isFirst}\n aria-label=\"Move up\"\n className=\"size-7\"\n >\n <ChevronUp className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => onMoveRow(id, 'down')}\n disabled={isLast}\n aria-label=\"Move down\"\n className=\"size-7\"\n >\n <ChevronDown className=\"size-4\" />\n </Button>\n </div>\n )\n}\n`\n}\n\n// ============================================================================\n// Truncate Helper Template\n// ============================================================================\n\nexport function generateTruncateHelper(): string {\n return `\nfunction truncateStr(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str\n return str.slice(0, maxLength) + '...'\n}\n`\n}\n","/**\n * Custom cell component generator — creates stub cell components for custom column types\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\n\nexport function createCustomCellComponent(\n schema: Schema,\n componentName: string,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions\n): void {\n const cellsDir = path.join(cwd, pagesDir, schema.name, 'cells')\n const componentFilePath = path.join(cellsDir, `${componentName}.tsx`)\n\n if (fs.existsSync(componentFilePath) && !options.force) return\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n const content = `import type { ${Singular}Data } from '@cms/actions/${schema.name}'\n\ninterface ${componentName}Props {\n data: ${Singular}Data\n}\n\nexport function ${componentName}({ data }: ${componentName}Props) {\n return (\n <div>\n {JSON.stringify(data)}\n </div>\n )\n}\n`\n\n if (!fs.existsSync(cellsDir)) {\n fs.mkdirSync(cellsDir, { recursive: true })\n }\n fs.writeFileSync(componentFilePath, content, 'utf-8')\n}\n","/**\n * Generator 9: Create page — (authenticated)/<n>/new/page.tsx\n * Generates server page component for creating a new entity\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, singularizeLabel, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface CreatePageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate create page component for adding a new entity\n */\nexport function generateCreatePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): CreatePageGeneratorResult {\n const newDir = path.join(cwd, pagesDir, schema.name, 'new')\n const pageFilePath = path.join(newDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const singLabel = singularizeLabel(schema.label)\n const kebabName = toKebabCase(schema.name)\n\n const content = `import { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { connection } from 'next/server'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { ${Singular}Form } from '../${kebabName}-form'\n\nexport default async function Create${Singular}Page() {\n await connection()\n\n return (\n <>\n <PageHeader title=\"Create ${singLabel}\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/${schema.name}\"><ChevronLeft /></Link></Button>} />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form key={Date.now()} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(newDir)) {\n fs.mkdirSync(newDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'new', 'page.tsx')]\n }\n}\n","/**\n * Generator 1: Database schema — append table to cms/db/schema.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../core/constants.js'\nimport { flattenFields, getManyToManyFields } from '../core/field-helpers/index.js'\nimport { toDrizzleType } from '../core/type-mappers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize } from '../utils/string.js'\n\n// ============================================================================\n// Field Modifiers\n// ============================================================================\n\nfunction getFieldModifiers(field: SchemaField, needsSql: { value: boolean }): string {\n const modifiers: string[] = []\n\n if (field.primaryKey) {\n modifiers.push('.primaryKey()')\n }\n\n const isDateField = field.type === 'date' || field.type === 'timestamp'\n const hasValidDefault =\n field.default !== undefined && field.default !== null && !(isDateField && field.default === '')\n\n if (hasValidDefault) {\n if (typeof field.default === 'string') {\n modifiers.push(`.default('${field.default}')`)\n } else {\n modifiers.push(`.default(${field.default})`)\n }\n }\n\n if (field.name === 'createdAt' || field.name === 'updatedAt') {\n modifiers.push('.default(sql`CURRENT_TIMESTAMP`)')\n needsSql.value = true\n }\n\n if (field.required || field.primaryKey) {\n modifiers.push('.notNull()')\n }\n\n return modifiers.join('')\n}\n\n// ============================================================================\n// Table Generation\n// ============================================================================\n\nfunction generateTableDefinition(\n schema: Schema,\n requiredImports: Set<string>,\n needsSql: { value: boolean }\n): string {\n const tableName = toPascalCase(schema.name)\n const variableName = toCamelCase(schema.name)\n\n requiredImports.add('pgTable')\n\n // Flatten fields, exclude M2M relationships (handled via junction tables)\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true) && !isLayoutField(f.type)\n )\n\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = dbFields.some((f) => f.name === 'published')\n\n const fieldDefs = dbFields\n .map((field) => {\n const drizzleType = toDrizzleType(field, requiredImports)\n const modifiers = getFieldModifiers(field, needsSql)\n const line = ` ${field.name}: ${drizzleType}${modifiers}`\n\n if ((field.type === 'richtext' || field.type === 'markdown') && field.output === 'html') {\n const snakeName = field.name.replace(/([A-Z])/g, '_$1').toLowerCase()\n requiredImports.add('text')\n return `${line},\\n ${field.name}Html: text('${snakeName}_html')`\n }\n\n return line\n })\n .join(',\\n')\n\n // Auto-add published field for draft mode\n let publishedField = ''\n if (hasDraftMode && !hasPublishedField) {\n requiredImports.add('boolean')\n publishedField = `,\\n published: boolean().notNull().default(false)`\n }\n\n // Auto-add timestamps\n const hasCreatedAt = dbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = dbFields.some((f) => f.name === 'updatedAt')\n let timestampFields = ''\n if (!hasCreatedAt || !hasUpdatedAt) {\n requiredImports.add('timestamp')\n needsSql.value = true\n }\n if (!hasCreatedAt) {\n timestampFields += `,\\n createdAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()`\n }\n if (!hasUpdatedAt) {\n timestampFields += `,\\n updatedAt: timestamp({ precision: 3, mode: 'string' }).default(sql\\`CURRENT_TIMESTAMP\\`).notNull()`\n }\n\n // Auto-add sortOrder for drag-and-drop reordering (skip for single schemas)\n const isSingle = schema.type === 'single'\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n let sortOrderField = ''\n if (!isSingle && !hasSortOrder) {\n requiredImports.add('integer')\n sortOrderField = `,\\n sortOrder: integer().notNull().default(0)`\n }\n\n return `\\nexport const ${variableName} = pgTable(\\n '${tableName}',\\n {\\n${fieldDefs}${publishedField}${timestampFields}${sortOrderField}\\n }\\n)\\n`\n}\n\nfunction generateJunctionTable(\n schemaName: string,\n field: SchemaField,\n requiredImports: Set<string>\n): string {\n const singularSchema = singularize(schemaName)\n const singularRelation = singularize(field.relationship || '')\n const junctionName = `${singularSchema}${toPascalCase(field.relationship || '')}`\n const junctionPascal = toPascalCase(junctionName)\n const schemaIdCol = `${singularSchema}Id`\n const relationIdCol = `${singularRelation}Id`\n const schemaTableRef = toCamelCase(schemaName)\n const relationTableRef = toCamelCase(field.relationship || '')\n\n requiredImports.add('pgTable')\n requiredImports.add('integer')\n requiredImports.add('primaryKey')\n\n return `\\nexport const ${toCamelCase(junctionName)} = pgTable(\\n '${junctionPascal}',\\n {\\n ${schemaIdCol}: integer().notNull().references(() => ${schemaTableRef}.id, { onDelete: 'cascade' }),\\n ${relationIdCol}: integer().notNull().references(() => ${relationTableRef}.id, { onDelete: 'cascade' })\\n },\\n (table) => [primaryKey({ columns: [table.${schemaIdCol}, table.${relationIdCol}] })]\\n)\\n`\n}\n\n// ============================================================================\n// Import Merging\n// ============================================================================\n\nfunction mergeImports(content: string, requiredImports: Set<string>, needsSql: boolean): string {\n const pgCoreMatch = content.match(/import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/)\n\n // Use regex to detect sql import — handles single/double quotes, extra whitespace, semicolons\n const drizzleOrmMatch = content.match(/import\\s*\\{([^}]*)\\}\\s*from\\s*['\"]drizzle-orm['\"]/)\n const existingDrizzleOrmImports = new Set<string>()\n if (drizzleOrmMatch) {\n drizzleOrmMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n .forEach((i) => {\n existingDrizzleOrmImports.add(i)\n })\n }\n const hasSqlImport = existingDrizzleOrmImports.has('sql')\n\n // Collect existing pg-core imports\n const existing = new Set<string>()\n if (pgCoreMatch) {\n pgCoreMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter(Boolean)\n .forEach((i) => {\n existing.add(i)\n })\n }\n\n const merged = new Set([...existing, ...requiredImports])\n const sorted = Array.from(merged).sort()\n const newImport = `import {\\n ${sorted.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n\n let updated = content\n\n if (pgCoreMatch) {\n updated = updated.replace(/import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/, newImport)\n } else if (drizzleOrmMatch) {\n updated = updated.replace(\n /import\\s*\\{[^}]*\\}\\s*from\\s*['\"]drizzle-orm['\"]/,\n (match) => `${match}\\n${newImport}`\n )\n } else {\n updated = `${newImport}\\n${updated}`\n }\n\n if (needsSql && !hasSqlImport) {\n if (drizzleOrmMatch) {\n // Add sql to existing drizzle-orm import\n existingDrizzleOrmImports.add('sql')\n const sortedOrm = Array.from(existingDrizzleOrmImports).sort()\n updated = updated.replace(\n /import\\s*\\{[^}]*\\}\\s*from\\s*['\"]drizzle-orm['\"]/,\n `import { ${sortedOrm.join(', ')} } from 'drizzle-orm'`\n )\n } else {\n updated = `import { sql } from 'drizzle-orm'\\n${updated}`\n }\n }\n\n return updated\n}\n\n// ============================================================================\n// Table End Finder (for --force replacement)\n// ============================================================================\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n return i + 1\n }\n }\n\n return content.length\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface DatabaseGeneratorResult {\n files: string[]\n tableName: string\n junctionTables: string[]\n}\n\n/**\n * Generate database schema for an entity — appends to cms/db/schema.ts\n */\nexport function generateDatabase(\n schema: Schema,\n cwd: string,\n schemaDir: string,\n options: GeneratorOptions = {}\n): DatabaseGeneratorResult {\n const schemaFilePath = path.join(cwd, schemaDir)\n const files: string[] = []\n\n // Read existing schema.ts\n let content = ''\n if (fs.existsSync(schemaFilePath)) {\n content = fs.readFileSync(schemaFilePath, 'utf-8')\n }\n\n const variableName = toCamelCase(schema.name)\n\n // Check for existing table\n if (content.includes(`export const ${variableName} =`) && !options.force) {\n return {\n files: [],\n tableName: variableName,\n junctionTables: []\n }\n }\n\n const requiredImports = new Set<string>()\n const needsSql = { value: false }\n\n // Generate main table\n const tableDef = generateTableDefinition(schema, requiredImports, needsSql)\n\n // Generate junction tables for M2M\n const m2mFields = getManyToManyFields(schema.fields)\n const junctionDefs = m2mFields.map((f) => generateJunctionTable(schema.name, f, requiredImports))\n const junctionNames = m2mFields.map((f) => {\n const s = singularize(schema.name)\n return toCamelCase(`${s}${toPascalCase(f.relationship || '')}`)\n })\n\n let updated = content\n\n if (options.force && content.includes(`export const ${variableName} =`)) {\n // Replace existing table definition\n const start = content.indexOf(`export const ${variableName} =`)\n const end = findTableEnd(content, start)\n updated = content.slice(0, start) + tableDef.trim() + content.slice(end)\n } else {\n // Append new table\n updated = `${updated.trimEnd()}\\n${tableDef}`\n }\n\n // Handle junction tables\n for (let i = 0; i < m2mFields.length; i++) {\n const jName = junctionNames[i]\n if (options.force && updated.includes(`export const ${jName} =`)) {\n const start = updated.indexOf(`export const ${jName} =`)\n const end = findTableEnd(updated, start)\n updated = updated.slice(0, start) + junctionDefs[i].trim() + updated.slice(end)\n } else if (!updated.includes(`export const ${jName} =`)) {\n updated = `${updated.trimEnd()}\\n${junctionDefs[i]}`\n }\n }\n\n // Merge imports\n updated = mergeImports(updated, requiredImports, needsSql.value)\n\n // Write\n const dir = path.dirname(schemaFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(schemaFilePath, updated, 'utf-8')\n files.push(schemaDir)\n\n return {\n files,\n tableName: variableName,\n junctionTables: junctionNames\n }\n}\n","/**\n * Generator 10: Edit page — (authenticated)/<n>/[id]/edit/page.tsx\n * Generates server page component for editing an existing entity\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface EditPageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate edit page component for updating an existing entity\n */\nexport function generateEditPage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): EditPageGeneratorResult {\n const editDir = path.join(cwd, pagesDir, schema.name, '[id]', 'edit')\n const pageFilePath = path.join(editDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const camelSingular = toCamelCase(singular)\n const kebabName = toKebabCase(schema.name)\n\n const content = `import { ChevronLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { connection } from 'next/server'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { get${Singular}ById } from '@cms/actions/${schema.name}'\nimport { ${Singular}Form } from '../../${kebabName}-form'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Edit${Singular}Page({ params }: PageProps) {\n const { id } = await params\n await connection()\n const ${camelSingular} = await get${Singular}ById(Number.parseInt(id, 10))\n\n if (!${camelSingular}) {\n notFound()\n }\n\n return (\n <>\n <PageHeader title=\"Edit ${Singular}\" back={<Button variant=\"ghost\" size=\"icon\" asChild><Link href=\"/cms/${schema.name}\"><ChevronLeft /></Link></Button>} />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form key={${camelSingular}.id} initialData={${camelSingular}} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(editDir)) {\n fs.mkdirSync(editDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, '[id]', 'edit', 'page.tsx')]\n }\n}\n","/**\n * Entity form generator — create/edit form with Zod validation, React Hook Form, and mutations\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields, hasFieldType, hasIconUsage } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, singularize, pluralize } from '../../utils/string.js'\nimport { generateFieldJSX } from './field-jsx.js'\nimport {\n type FormGeneratorResult,\n collectRelationshipFields,\n buildZodFields,\n buildDefaultValues,\n buildUiImports\n} from './form-shared.js'\n\nexport function generateForm(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): FormGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const formFilePath = path.join(entityDir, `${schema.name}-form.tsx`)\n\n if (fs.existsSync(formFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n\n // Analyze fields\n const allFormFields = schema.fields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n const flatFields = flattenFields(allFormFields)\n const hasDraft = schema.actions?.draft === true\n\n // Collect tab field names\n const tabFieldNames = new Set<string>()\n for (const f of schema.fields) {\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) for (const tf of tab.fields) tabFieldNames.add(tf.name)\n }\n }\n }\n\n // Check what components are needed\n const hasBoolean = hasFieldType(schema.fields, 'boolean')\n const hasImage = hasFieldType(schema.fields, 'image')\n const hasVideo = hasFieldType(schema.fields, 'video')\n const hasMedia = hasFieldType(schema.fields, 'media')\n const hasIcon = hasFieldType(schema.fields, 'icon')\n const hasIconPostfix = hasIconUsage(schema.fields)\n const hasDate = hasFieldType(schema.fields, 'date')\n const hasSelect = hasFieldType(schema.fields, 'select')\n const hasMarkdown = hasFieldType(schema.fields, 'markdown')\n const hasRichtext = hasFieldType(schema.fields, 'richtext')\n const hasTextarea = hasFieldType(schema.fields, 'text')\n const hasSeparator = hasFieldType(schema.fields, 'separator')\n const hasRelationship = hasFieldType(schema.fields, 'relationship')\n const hasTabsField = schema.fields.some((f) => f.type === 'tabs')\n const tabsField = schema.fields.find((f) => f.type === 'tabs')\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n const mainRelFields = collectRelationshipFields(schema.fields, tabFieldNames)\n\n // Collect list fields with nested fields (need useFieldArray hooks)\n const listFieldsWithNested: SchemaField[] = []\n function collectListFields(fields: SchemaField[]): void {\n for (const f of fields) {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n listFieldsWithNested.push(f)\n }\n if (f.type === 'group' && f.fields) collectListFields(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collectListFields(tab.fields)\n }\n }\n }\n }\n collectListFields(allFormFields)\n const hasList = hasFieldType(schema.fields, 'list')\n const hasNestedList = listFieldsWithNested.length > 0\n // Simple list uses DynamicListField; nested list uses useFieldArray + Accordion\n const hasSimpleList =\n hasList && flatFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n\n // Build Zod schema\n const zodFields = buildZodFields(flatFields)\n\n // Build default values\n const defaultValues = buildDefaultValues(flatFields)\n\n // Build form fields JSX\n const formFieldsJSX = allFormFields\n .filter((f) => !(hasDraft && f.name === 'published'))\n .map((f) => {\n if (f.type === 'tabs' && f.tabs) {\n const tabsList = f.tabs\n .map((t) => ` <TabsTrigger value=\"${t.name}\">${t.label}</TabsTrigger>`)\n .join('\\n')\n const tabsContent = f.tabs\n .map((t) => {\n const tabFields = (t.fields || [])\n .map((tf) => generateFieldJSX(tf, ' '))\n .join('\\n')\n return ` <TabsContent value=\"${t.name}\" className=\"space-y-6 p-6 rounded-2xl border bg-card\">\n${tabFields}\n </TabsContent>`\n })\n .join('\\n')\n return ` <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n </Tabs>`\n }\n if (tabFieldNames.has(f.name)) return ''\n return generateFieldJSX(f)\n })\n .filter(Boolean)\n .join('\\n')\n\n // --- Build imports ---\n const uiImports = buildUiImports({\n hasBoolean,\n hasTextarea,\n hasImage,\n hasVideo,\n hasMedia,\n hasIcon,\n hasIconPostfix,\n hasDate,\n hasMarkdown,\n hasRichtext,\n hasSeparator,\n hasSelect,\n hasTabsField,\n hasRelationship,\n hasSimpleList,\n hasNestedList\n })\n\n // Lucide icons\n const lucideIcons: string[] = []\n if (hasRelationship) lucideIcons.push('Check', 'ChevronsUpDown')\n if (hasNestedList) {\n if (!lucideIcons.includes('Plus')) lucideIcons.push('Plus')\n if (!lucideIcons.includes('X')) lucideIcons.push('X')\n }\n\n // Relationship hooks\n const relHookImports = mainRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relPlural} } from '@cms/hooks/use-${f.relationship}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // Relationship state\n const relState = mainRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return ` const [${f.name}Open, set${toPascalCase(f.name)}Open] = React.useState(false)\n const { data: ${f.relationship}Data } = use${relPlural}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // List field array hooks\n const fieldArrayHooks = listFieldsWithNested\n .map((field) => {\n const pascalFieldName = toPascalCase(field.name)\n return ` const [${field.name}Expanded, set${pascalFieldName}Expanded] = React.useState<string | undefined>(undefined)\n const ${field.name}FieldArray = useFieldArray({\n control: form.control,\n name: '${field.name}'\n })`\n })\n .join('\\n')\n\n const needsReact = mainRelFields.length > 0 || hasNestedList\n\n // --- Assemble file ---\n const content = `'use client'\n${needsReact ? \"\\nimport * as React from 'react'\" : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideIcons.length > 0 ? `\\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\nimport { useRouter } from 'next/navigation'\nimport {${hasNestedList ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod/v3'${hasTabsField ? \"\\nimport { useQueryState } from 'nuqs'\" : ''}${hasRelationship ? \"\\nimport { cn } from '@cms/utils/cn'\" : ''}\n${relHookImports ? `${relHookImports}\\n` : ''}${uiImports.join('\\n')}\nimport type {\n Create${Singular}Input,\n ${Singular}Data,\n Update${Singular}Input\n} from '@cms/actions/${schema.name}'\nimport { create${Singular}, update${Singular} } from '@cms/actions/${schema.name}'\n\nconst formSchema = z.object({\n${zodFields}\n})\n\nexport type FormValues = z.infer<typeof formSchema>\n\ninterface ${Singular}FormProps {\n initialData?: ${Singular}Data\n}\n\nexport function ${Singular}Form({ initialData }: ${Singular}FormProps) {\n const router = useRouter()\n const queryClient = useQueryClient()${hasTabsField ? `\\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${firstTabName}' })` : ''}${relState ? `\\n${relState}` : ''}\n\n const createMutation = useMutation({\n mutationFn: (data: Create${Singular}Input) => create${Singular}(data),\n onSuccess: async () => {\n toast.success('${Singular} created successfully')\n await queryClient.invalidateQueries({ queryKey: ['${plural}'] })\n router.push('/cms/${schema.name}')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to create ${singular}')\n }\n })\n\n const updateMutation = useMutation({\n mutationFn: (data: Update${Singular}Input) => update${Singular}(data),\n onSuccess: () => {\n toast.success('${Singular} updated successfully')\n queryClient.invalidateQueries({ queryKey: ['${plural}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update ${singular}')\n }\n })\n\n const isPending = createMutation.isPending || updateMutation.isPending\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaultValues}\n }\n })\n${fieldArrayHooks ? `\\n${fieldArrayHooks}\\n` : ''}\n function onSubmit(values: FormValues${hasDraft ? ', publishedValue: boolean = false' : ''}) {\n const cleanedValues = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [key, value === undefined ? '' : value])\n ) as FormValues\n\n if (initialData) {\n updateMutation.mutate({\n id: initialData.id as number,\n ...cleanedValues${hasDraft ? ',\\n published: publishedValue' : ''}\n })\n } else {\n const { id: _id, ...createValues } = cleanedValues\n createMutation.mutate({\n ...createValues${hasDraft ? ',\\n published: publishedValue' : ''}\n } as Create${Singular}Input)\n }\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-form\" onSubmit={form.handleSubmit((values) => onSubmit(values${hasDraft ? ', false' : ''}), (errors) => {\n console.error('Form validation errors:', errors)\n const firstError = Object.values(errors)[0]\n if (firstError?.message) {\n toast.error(String(firstError.message))\n } else {\n toast.error('Please fix the form errors before submitting')\n }\n })} className=\"space-y-6\">\n <div className=\"space-y-6 p-6 rounded-2xl border bg-card\">\n${formFieldsJSX}\n </div>\n\n <div className=\"flex items-center fixed bottom-0 md:left-[calc(var(--sidebar-width))] w-screen md:w-[calc(100svw-var(--sidebar-width)-4px)] right-0 bg-secondary border-t\">\n <div className=\"flex mx-auto py-4 w-full max-w-5xl items-center justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push('/cms/${schema.name}')}\n disabled={isPending}\n size=\"lg\"\n >\n Cancel\n </Button>\n${\n hasDraft\n ? ` <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isPending ? 'Saving...' : 'Save as Draft'}\n </Button>\n <Button\n type=\"button\"\n variant=\"default\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, true))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isPending ? 'Publishing...' : initialData ? 'Update & Publish' : 'Publish'}\n </Button>`\n : ` <Button type=\"submit\" disabled={isPending} size=\"lg\">\n {isPending ? 'Saving...' : initialData ? 'Update' : 'Create'}\n </Button>`\n}\n </div>\n </div>\n </form>\n </Form>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, `${schema.name}-form.tsx`)]\n }\n}\n","/**\n * Zod schema generation helpers for entity/single forms\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\n\nexport function getFormFieldType(field: SchemaField): string {\n switch (field.type) {\n case 'boolean':\n return 'checkbox'\n case 'text':\n return 'textarea'\n case 'markdown':\n return 'markdown'\n case 'richtext':\n return 'richtext'\n case 'number':\n case 'decimal':\n return 'number'\n case 'date':\n return 'date'\n case 'time':\n return 'time'\n case 'timestamp':\n return 'datetime-local'\n default:\n return 'text'\n }\n}\n\nexport function getZodType(field: SchemaField): string {\n const label = field.label || field.name\n\n switch (field.type) {\n case 'serial':\n case 'number':\n case 'decimal':\n return field.required\n ? `z.number({ message: '${label} is required' })`\n : 'z.number().optional()'\n case 'boolean':\n return 'z.boolean()'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n case 'richtext': {\n if (field.name.toLowerCase().includes('email')) {\n const base = field.required\n ? `z.string().min(1, '${label} is required').email('Please enter a valid email address')`\n : `z.string().email('Please enter a valid email address').optional()`\n return field.length ? `${base}.max(${field.length})` : base\n }\n const base = field.required ? `z.string().min(1, '${label} is required')` : 'z.string()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'date':\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n return `z.string().min(1, '${label} is required')`\n case 'timestamp':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'image':\n case 'video':\n case 'media': {\n if (!field.required) {\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const base = `z.string().min(1, 'Please upload ${label.toLowerCase()}').url('Please provide a valid URL')`\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'list':\n if (field.fields && field.fields.length > 0) {\n const nested = field.fields\n .flatMap((nf) => {\n const defs: string[] = []\n const zodType = getZodType(nf)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(nf.name)}: ${zodType}`\n if (!nf.required && !alreadyOptional) def += '.optional()'\n defs.push(def)\n if (nf.hasIcon)\n defs.push(` ${quotePropertyName(`${nf.name}Icon`)}: z.string().optional()`)\n return defs\n })\n .join(',\\n')\n const obj = `z.object({\\n${nested}\\n })`\n const arr = field.maxItems ? `z.array(${obj}).max(${field.maxItems})` : `z.array(${obj})`\n return field.required\n ? `${arr}.min(1, '${label} must have at least one item')`\n : `${arr}.optional()`\n }\n return field.required\n ? `z.array(z.string()).min(1, '${label} must have at least one item')`\n : 'z.array(z.string()).optional()'\n case 'select': {\n if (field.options && field.options.length > 0) {\n const values = field.options.map((o) => `'${o.value}'`).join(', ')\n const arr = `[${values}] as const`\n return field.required\n ? `z.string().min(1, '${label} is required').refine((val) => (${arr} as readonly string[]).includes(val), { message: 'Invalid ${label}' })`\n : `z.string().refine((val) => !val || (${arr} as readonly string[]).includes(val), { message: 'Invalid ${label}' }).optional()`\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'icon':\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'relationship':\n if (field.multiple) {\n return field.required\n ? `z.array(z.number()).min(1, '${label} is required')`\n : 'z.array(z.number()).optional()'\n }\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n case 'group':\n if (field.fields && field.fields.length > 0) {\n const nested = field.fields\n .map((nf) => {\n const zodType = getZodType(nf)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(nf.name)}: ${zodType}`\n if (!nf.required && !alreadyOptional) def += '.optional()'\n return def\n })\n .join(',\\n')\n return field.required\n ? `z.object({\\n${nested}\\n })`\n : `z.object({\\n${nested}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n","/**\n * List/nested-list JSX generation for form fields\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\n\nexport function renderListField(field: SchemaField, indent: string, label: string): string {\n const listHintJSX = field.hint\n ? `${indent} <p className=\"text-[0.8rem] text-muted-foreground\">${field.hint}</p>`\n : ''\n\n // Simple string list — use DynamicListField\n if (!field.fields || field.fields.length === 0) {\n return `${indent}<DynamicListField\n${indent} name=\"${field.name}\"\n${indent} label=\"${label}\"\n${indent} disabled={isPending}${field.maxItems ? `\\n${indent} maxItems={${field.maxItems}}` : ''}\n${indent} placeholder=\"Enter value\"\n${indent}/>`\n }\n\n // Nested fields list — useFieldArray + Accordion\n const singularLabel = singularize(label)\n const pascalFieldName = toPascalCase(field.name)\n\n // Find title field for accordion header\n const stringTypes = ['string', 'varchar', 'text']\n const titleField =\n field.fields.find((f) => f.name === 'title' && stringTypes.includes(f.type)) ||\n field.fields.find((f) => f.name === 'name' && stringTypes.includes(f.type)) ||\n field.fields.find((f) => stringTypes.includes(f.type))\n const accordionTitle = titleField\n ? `{form.watch(\\`${field.name}.\\${index}.${titleField.name}\\`) || '${singularLabel} ' + (index + 1)}`\n : `${singularLabel} {index + 1}`\n\n // Generate nested field JSX\n const nestedFieldsJSX = field.fields\n .map((nf) => {\n const nestedLabel = nf.label || nf.name\n const nestedHint = nf.hint\n ? `\\n${indent} <FormDescription>${nf.hint}</FormDescription>`\n : ''\n if (nf.type === 'boolean') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox checked={formField.value} onCheckedChange={formField.onChange} disabled={isPending} />\n${indent} </FormControl>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'image') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={10} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'video') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <VideoUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={100} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nf.type === 'media') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <MediaUploadField value={formField.value} onChange={formField.onChange} onBlur={formField.onBlur} disabled={isPending} maxSizeInMB={100} label=\"\" />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n // Default: text input for nested fields\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input placeholder=\"Enter ${nestedLabel.toLowerCase()}\" disabled={isPending} {...formField} />\n${indent} </FormControl>${nestedHint}\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n })\n .join('\\n')\n\n return `${indent}<FormItem>\n${indent} {${field.name}FieldArray.fields.length === 0 && (\n${indent} <div className=\"text-sm text-muted-foreground rounded-lg border border-dashed p-6 text-center\">\n${indent} <p>No ${label.toLowerCase()} added yet.</p>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} className=\"mt-2\"\n${indent} onClick={() => {\n${indent} ${field.name}FieldArray.append({${field.fields.map((nf) => `${nf.name}: ${nf.type === 'boolean' ? 'false' : \"''\"}`).join(', ')}})\n${indent} set${pascalFieldName}Expanded(\\`item-\\${${field.name}FieldArray.fields.length + 1}\\`)\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className=\"size-3\" />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${indent} )}\n${indent} {${field.name}FieldArray.fields.length > 0 && (\n${indent} <div className=\"space-y-5\">\n${indent} <div className=\"flex items-center justify-between\">\n${indent} <Label className=\"text-base\">${label}</Label>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} ${field.name}FieldArray.append({${field.fields.map((nf) => `${nf.name}: ${nf.type === 'boolean' ? 'false' : \"''\"}`).join(', ')}})\n${indent} set${pascalFieldName}Expanded(\\`item-\\${${field.name}FieldArray.fields.length + 1}\\`)\n${indent} }}\n${indent} disabled={isPending${field.maxItems ? ` || ${field.name}FieldArray.fields.length >= ${field.maxItems}` : ''}}\n${indent} >\n${indent} <Plus className=\"size-3\" />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${listHintJSX ? `${listHintJSX}\\n` : ''}${indent} <Accordion\n${indent} type=\"single\"\n${indent} collapsible\n${indent} className=\"w-full gap-1 flex flex-col\"\n${indent} value={${field.name}Expanded}\n${indent} onValueChange={set${pascalFieldName}Expanded}\n${indent} >\n${indent} {${field.name}FieldArray.fields.map((item, index) => (\n${indent} <AccordionItem\n${indent} key={item.id}\n${indent} value={\\`item-\\${index + 1}\\`}\n${indent} className=\"p-0 border-none\"\n${indent} >\n${indent} <div className=\"space-y-5 rounded-lg border p-4 bg-secondary/50 [&_h3]:m-0 w-full\">\n${indent} <AccordionTrigger className=\"flex items-center p-0 justify-between w-full\">\n${indent} <h4 className=\"text-sm font-medium w-full\">\n${indent} ${accordionTitle}\n${indent} </h4>\n${indent} <Button\n${indent} asChild\n${indent} variant=\"ghost\"\n${indent} size=\"sm\"\n${indent} disabled={isPending}\n${indent} >\n${indent} <span\n${indent} role=\"button\"\n${indent} tabIndex={0}\n${indent} onClick={(e) => { e.stopPropagation(); ${field.name}FieldArray.remove(index); }}\n${indent} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); e.stopPropagation(); ${field.name}FieldArray.remove(index); } }}\n${indent} className=\"cursor-pointer\"\n${indent} >\n${indent} <X className=\"size-3\" />\n${indent} </span>\n${indent} </Button>\n${indent} </AccordionTrigger>\n${indent} <AccordionContent className=\"flex flex-col gap-4 px-1\">\n${indent} <Separator className=\"mt-2\" />\n${indent} <div className=\"space-y-5\">\n${nestedFieldsJSX}\n${indent} </div>\n${indent} </AccordionContent>\n${indent} </div>\n${indent} </AccordionItem>\n${indent} ))}\n${indent} </Accordion>\n${indent} </div>\n${indent} )}\n${indent}</FormItem>`\n}\n","/**\n * Form field JSX generation — dispatcher + per-type renderers\n */\n\nimport type { SchemaField } from '../../types.js'\nimport { toPascalCase, singularize } from '../../utils/string.js'\nimport { getFormFieldType } from './zod-schema.js'\nimport { renderListField } from './field-jsx-nested.js'\n\nexport interface FieldJSXOptions {\n skipLabel?: boolean\n}\n\nfunction generateIconPostfix(field: SchemaField, indent: string): string {\n const label = field.label || field.name\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}Icon\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label} Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} triggerPlaceholder=\"Select icon\"\n${indent} />\n${indent} </FormControl>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nexport function generateFieldJSX(field: SchemaField, indent = ' ', options?: FieldJSXOptions): string {\n if (field.hidden) return ''\n\n let mainJSX = generateFieldJSXCore(field, indent)\n if (!mainJSX) return ''\n\n if (options?.skipLabel) {\n mainJSX = mainJSX\n .split('\\n')\n .filter(line => !line.includes('<FormLabel>'))\n .join('\\n')\n }\n\n if (field.hasIcon) {\n return `${mainJSX}\\n${generateIconPostfix(field, indent)}`\n }\n\n return mainJSX\n}\n\nfunction generateFieldJSXCore(field: SchemaField, indent = ' '): string {\n const fieldType = getFormFieldType(field)\n const label = field.label || field.name\n const hintJSX = field.hint\n ? `${indent} <FormDescription>${field.hint}</FormDescription>`\n : ''\n\n if ((field.type === 'group' || field.type === 'section') && field.fields) return renderGroupField(field, indent, label)\n if (field.type === 'separator') return renderSeparatorField(field, indent)\n if (field.type === 'boolean') return renderBooleanField(field, indent, label, hintJSX)\n if (field.type === 'image') return renderImageField(field, indent, label, hintJSX)\n if (field.type === 'video') return renderVideoField(field, indent, label, hintJSX)\n if (field.type === 'media') return renderMediaField(field, indent, label, hintJSX)\n if (field.type === 'icon') return renderIconField(field, indent, label, hintJSX)\n if (field.type === 'date') return renderDateField(field, indent, label, hintJSX)\n if (field.type === 'select') return renderSelectField(field, indent, label, hintJSX)\n if (field.type === 'richtext') return renderRichtextField(field, indent, label, hintJSX)\n if (field.type === 'markdown') return renderMarkdownField(field, indent, label, hintJSX)\n if (field.type === 'text') return renderTextareaField(field, indent, label, hintJSX)\n if (field.type === 'relationship' && field.relationship)\n return renderRelationshipField(field, indent, label, hintJSX)\n if (field.type === 'list') return renderListField(field, indent, label)\n\n return renderDefaultField(field, indent, label, fieldType, hintJSX)\n}\n\nfunction renderGroupField(field: SchemaField, indent: string, label: string): string {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields!.map((nf) => generateFieldJSX(nf, `${indent} `)).join('\\n')\n const heading =\n label && label !== field.name\n ? `${indent}<h3 className=\"text-lg font-medium\">${label}</h3>\\n`\n : ''\n return `${indent}<div className=\"space-y-5\">\n${heading}${indent} <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n${indent} </div>\n${indent}</div>`\n}\n\nfunction renderSeparatorField(field: SchemaField, indent: string): string {\n if (field.label) {\n return `${indent}<div className=\"relative my-4\">\n${indent} <div className=\"absolute inset-0 flex items-center\">\n${indent} <Separator className=\"w-full\" />\n${indent} </div>\n${indent} <div className=\"relative flex justify-center text-xs uppercase\">\n${indent} <span className=\"bg-background px-2 text-muted-foreground\">${field.label}</span>\n${indent} </div>\n${indent}</div>`\n }\n return `${indent}<Separator className=\"my-4\" />`\n}\n\nfunction renderBooleanField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={formField.value}\n${indent} onCheckedChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${label}</FormLabel>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} </div>\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderImageField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={10}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderVideoField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <VideoUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={100}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderMediaField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <MediaUploadField\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} onBlur={formField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={100}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderIconField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} triggerPlaceholder=\"Select ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderDateField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <DatePicker\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} placeholder=\"Select ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderSelectField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n const options = field.options || []\n const optionsJSX = options\n .map(\n (o) =>\n `${indent} <SelectItem key=\"${o.value}\" value=\"${o.value}\">${o.label}</SelectItem>`\n )\n .join('\\n')\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Select\n${indent} value={formField.value}\n${indent} onValueChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} >\n${indent} <SelectTrigger>\n${indent} <SelectValue placeholder=\"Select ${label.toLowerCase()}\" />\n${indent} </SelectTrigger>\n${indent} <SelectContent>\n${optionsJSX}\n${indent} </SelectContent>\n${indent} </Select>\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderRichtextField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <RichTextEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} className=\"min-h-[300px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderMarkdownField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <MarkdownEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} componentSnippets={{}}\n${indent} className=\"min-h-[300px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderTextareaField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} className=\"min-h-[100px]\"\n${indent} disabled={isPending}\n${indent} {...formField}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string\n): string {\n const relName = field.relationship!\n const relSingular = singularize(relName)\n const relPascal = toPascalCase(relSingular)\n const displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n const dataArray = `${relName}Data?.${relName}`\n\n if (field.multiple) {\n return renderMultiRelationshipField(field, indent, label, hintJSX, displayField, dataArray, relSingular)\n }\n\n return renderSingleRelationshipField(field, indent, label, hintJSX, displayField, dataArray, relSingular)\n}\n\nfunction renderMultiRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string,\n displayField: string,\n dataArray: string,\n relSingular: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <Popover open={${field.name}Open} onOpenChange={set${toPascalCase(field.name)}Open}>\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\"w-full justify-between\", (!formField.value || formField.value.length === 0) && \"text-muted-foreground\")}\n${indent} disabled={isPending}\n${indent} >\n${indent} {(formField.value?.length ?? 0) > 0\n${indent} ? \\`\\${formField.value!.length} selected\\`\n${indent} : \"Select ${label.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n${indent} </Button>\n${indent} </FormControl>\n${indent} </PopoverTrigger>\n${indent} <PopoverContent className=\"w-full p-0\" align=\"start\">\n${indent} <Command>\n${indent} <CommandInput placeholder=\"Search ${label.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${relSingular} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.filter((item) => item.id !== null).map((item) => {\n${indent} const displayName = ${displayField}\n${indent} const isSelected = formField.value?.includes(item.id as number) || false\n${indent} return (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={displayName}\n${indent} onSelect={() => {\n${indent} const current = formField.value || []\n${indent} formField.onChange(isSelected\n${indent} ? current.filter((id: number) => id !== item.id)\n${indent} : [...current, item.id as number])\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 size-4\", isSelected ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {displayName}\n${indent} </CommandItem>\n${indent} )\n${indent} })}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderSingleRelationshipField(\n field: SchemaField,\n indent: string,\n label: string,\n hintJSX: string,\n displayField: string,\n dataArray: string,\n relSingular: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <Popover open={${field.name}Open} onOpenChange={set${toPascalCase(field.name)}Open}>\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\"w-full justify-between\", !formField.value && \"text-muted-foreground\")}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value\n${indent} ? (() => {\n${indent} const item = ${dataArray}?.find((item) => item.id !== null && String(item.id) === formField.value)\n${indent} return item ? (${displayField}) : \"Select ${label.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${label.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n${indent} </Button>\n${indent} </FormControl>\n${indent} </PopoverTrigger>\n${indent} <PopoverContent className=\"w-full p-0\" align=\"start\">\n${indent} <Command>\n${indent} <CommandInput placeholder=\"Search ${label.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${relSingular} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.filter((item) => item.id !== null).map((item) => {\n${indent} const displayName = ${displayField}\n${indent} return (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={displayName}\n${indent} onSelect={() => {\n${indent} formField.onChange(String(item.id))\n${indent} set${toPascalCase(field.name)}Open(false)\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 size-4\", formField.value === String(item.id) ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {displayName}\n${indent} </CommandItem>\n${indent} )\n${indent} })}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n\nfunction renderDefaultField(\n field: SchemaField,\n indent: string,\n label: string,\n fieldType: string,\n hintJSX: string\n): string {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${label}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${fieldType}\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} {...formField}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n}\n","/**\n * Shared logic for entity and single form generators\n */\n\nimport { isLayoutField } from '../../core/constants.js'\nimport type { SchemaField } from '../../types.js'\nimport { quotePropertyName } from '../../utils/string.js'\nimport { getZodType } from './zod-schema.js'\n\nexport interface FormGeneratorResult {\n files: string[]\n}\n\nexport function collectRelationshipFields(\n fields: SchemaField[],\n _tabFieldNames: Set<string>\n): SchemaField[] {\n const result: SchemaField[] = []\n const seen = new Set<string>()\n function collect(fieldsToCheck: SchemaField[]): void {\n for (const f of fieldsToCheck) {\n if (f.type === 'relationship' && f.relationship && !seen.has(f.name)) {\n seen.add(f.name)\n result.push(f)\n }\n if (f.type === 'group' && f.fields) collect(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collect(tab.fields)\n }\n }\n }\n }\n collect(fields)\n return result\n}\n\nexport function generateDefaultValue(f: SchemaField): string {\n if (f.type === 'list') return ` ${f.name}: initialData?.${f.name} ?? []`\n if (f.type === 'boolean') return ` ${f.name}: initialData?.${f.name} ?? false`\n if (f.type === 'number' || f.type === 'decimal' || f.type === 'serial') {\n const def = f.required ? '0' : 'undefined'\n return ` ${f.name}: initialData?.${f.name} ?? ${def}`\n }\n if (f.type === 'relationship') {\n if (f.multiple) return ` ${f.name}: initialData?.${f.name} ?? []`\n return ` ${f.name}: initialData?.${f.name}\n ? (typeof initialData.${f.name} === 'object' ? String(initialData.${f.name}.id) : String(initialData.${f.name}))\n : ''`\n }\n if (f.type === 'date' || f.type === 'timestamp') {\n return ` ${f.name}: initialData?.${f.name} ?? undefined`\n }\n if (f.default !== undefined && f.default !== null) {\n const def = typeof f.default === 'string' ? `'${f.default}'` : f.default\n return ` ${f.name}: initialData?.${f.name} ?? ${def}`\n }\n return ` ${f.name}: initialData?.${f.name} ?? ''`\n}\n\nexport function buildZodFields(flatFields: SchemaField[]): string {\n return flatFields\n .filter((f) => f.type !== 'tabs' && !isLayoutField(f.type))\n .flatMap((f) => {\n const defs: string[] = []\n const zodType = getZodType(f)\n const alreadyOptional = zodType.includes('.optional()')\n let def = ` ${quotePropertyName(f.name)}: ${zodType}`\n if (!f.required && !alreadyOptional) def += '.optional()'\n defs.push(def)\n if (f.hasIcon) defs.push(` ${quotePropertyName(`${f.name}Icon`)}: z.string().optional()`)\n return defs\n })\n .join(',\\n')\n}\n\nexport function buildDefaultValues(flatFields: SchemaField[]): string {\n return flatFields\n .filter((f) => f.type !== 'tabs' && !isLayoutField(f.type))\n .flatMap((f) => {\n const defs = [generateDefaultValue(f)]\n if (f.hasIcon) defs.push(` ${f.name}Icon: initialData?.${f.name}Icon ?? ''`)\n return defs\n })\n .join(',\\n')\n}\n\nexport function buildUiImports(ctx: {\n hasBoolean: boolean\n hasTextarea: boolean\n hasImage: boolean\n hasVideo: boolean\n hasMedia: boolean\n hasIcon: boolean\n hasIconPostfix: boolean\n hasDate: boolean\n hasMarkdown: boolean\n hasRichtext: boolean\n hasSeparator: boolean\n hasSelect: boolean\n hasTabsField: boolean\n hasRelationship: boolean\n hasSimpleList: boolean\n hasNestedList: boolean\n}): string[] {\n const uiImports: string[] = [\n \"import { Button } from '@cms/components/ui/button'\",\n \"import { Input } from '@cms/components/ui/input'\",\n `import {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage\n} from '@cms/components/ui/form'`\n ]\n\n if (ctx.hasBoolean) uiImports.push(\"import { Checkbox } from '@cms/components/ui/checkbox'\")\n if (ctx.hasTextarea) uiImports.push(\"import { Textarea } from '@cms/components/ui/textarea'\")\n if (ctx.hasImage)\n uiImports.push(\"import { ImageUploadField } from '@cms/components/ui/image-upload-field'\")\n if (ctx.hasVideo)\n uiImports.push(\"import { VideoUploadField } from '@cms/components/ui/video-upload-field'\")\n if (ctx.hasMedia)\n uiImports.push(\"import { MediaUploadField } from '@cms/components/ui/media-upload-field'\")\n if (ctx.hasIcon || ctx.hasIconPostfix)\n uiImports.push(\"import { IconPicker } from '@cms/components/ui/icon-picker'\")\n if (ctx.hasDate) uiImports.push(\"import { DatePicker } from '@cms/components/ui/date-picker'\")\n if (ctx.hasMarkdown)\n uiImports.push(\"import { MarkdownEditor } from '@cms/components/ui/markdown-editor'\")\n if (ctx.hasRichtext)\n uiImports.push(\"import { RichTextEditor } from '@cms/components/ui/rich-text-editor'\")\n if (ctx.hasSeparator) uiImports.push(\"import { Separator } from '@cms/components/ui/separator'\")\n if (ctx.hasSelect) {\n uiImports.push(`import {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue\n} from '@cms/components/ui/select'`)\n }\n if (ctx.hasTabsField) {\n uiImports.push(`import {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent\n} from '@cms/components/ui/tabs'`)\n }\n if (ctx.hasRelationship) {\n uiImports.push(`import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList\n} from '@cms/components/ui/command'`)\n uiImports.push(`import {\n Popover,\n PopoverContent,\n PopoverTrigger\n} from '@cms/components/ui/popover'`)\n }\n\n if (ctx.hasSimpleList)\n uiImports.push(\"import { DynamicListField } from '@cms/components/ui/dynamic-list-field'\")\n if (ctx.hasNestedList) {\n uiImports.push(`import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger\n} from '@cms/components/ui/accordion'`)\n if (!ctx.hasSeparator)\n uiImports.push(\"import { Separator } from '@cms/components/ui/separator'\")\n uiImports.push(\"import { Label } from '@cms/components/ui/label'\")\n }\n\n return uiImports\n}\n","/**\n * Single (singleton) form generator — Card-per-section with independent saves.\n * Top-level `section` fields each become a Card with their own useForm + useMutation.\n * Schemas without sections fall back to a single Card with all fields.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { isLayoutField } from '../../core/constants.js'\nimport { flattenFields, hasFieldType, hasIconUsage } from '../../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema, SchemaField } from '../../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize } from '../../utils/string.js'\nimport { generateFieldJSX } from './field-jsx.js'\nimport {\n type FormGeneratorResult,\n collectRelationshipFields,\n buildZodFields,\n buildDefaultValues,\n buildUiImports\n} from './form-shared.js'\n\n// ============================================================================\n// Card group parsing\n// ============================================================================\n\ninterface CardGroup {\n title: string\n description: string\n hint: string\n varPrefix: string\n componentName: string\n fields: SchemaField[]\n flatFields: SchemaField[]\n}\n\n/**\n * Parse schema fields into card groups.\n * - Top-level `section` fields each become a card.\n * - Fields without sections → one card (backward compat).\n */\nfunction parseCardGroups(allFormFields: SchemaField[], schemaLabel: string): CardGroup[] {\n const sections = allFormFields.filter((f) => f.type === 'section' && f.fields)\n const nonSections = allFormFields.filter((f) => f.type !== 'section' && !isLayoutField(f.type))\n\n // If no sections, all fields go in one card\n if (sections.length === 0) {\n const title = nonSections[0]?.label || nonSections[0]?.name || schemaLabel\n return [\n {\n title,\n description: '',\n hint: '',\n varPrefix: toCamelCase(nonSections[0]?.name || 'form'),\n componentName: `${toPascalCase(nonSections[0]?.name || 'form')}Card`,\n fields: nonSections,\n flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))\n }\n ]\n }\n\n // Each section becomes a card\n const groups: CardGroup[] = []\n for (const section of sections) {\n const innerFields = section.fields || []\n groups.push({\n title: section.label || section.name,\n description: section.description || '',\n hint: section.hint || '',\n varPrefix: toCamelCase(section.name),\n componentName: `${toPascalCase(section.name)}Card`,\n fields: innerFields,\n flatFields: flattenFields(innerFields).filter((f) => !isLayoutField(f.type))\n })\n }\n\n // If there are also loose fields outside sections, put them in a default card\n if (nonSections.length > 0) {\n const title = nonSections[0]?.label || nonSections[0]?.name || 'General'\n groups.unshift({\n title,\n description: '',\n hint: '',\n varPrefix: toCamelCase(nonSections[0]?.name || 'general'),\n componentName: `${toPascalCase(nonSections[0]?.name || 'General')}Card`,\n fields: nonSections,\n flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))\n })\n }\n\n return groups\n}\n\n// ============================================================================\n// Per-group analysis\n// ============================================================================\n\ninterface GroupAnalysis {\n relFields: SchemaField[]\n listFieldsWithNested: SchemaField[]\n hasTabsField: boolean\n firstTabName: string\n tabFieldNames: Set<string>\n}\n\nfunction analyzeGroup(fields: SchemaField[]): GroupAnalysis {\n const tabFieldNames = new Set<string>()\n for (const f of fields) {\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) for (const tf of tab.fields) tabFieldNames.add(tf.name)\n }\n }\n }\n\n const relFields = collectRelationshipFields(fields, tabFieldNames)\n\n const listFieldsWithNested: SchemaField[] = []\n function collectLists(flds: SchemaField[]): void {\n for (const f of flds) {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n listFieldsWithNested.push(f)\n }\n if (f.type === 'group' && f.fields) collectLists(f.fields)\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields) collectLists(tab.fields)\n }\n }\n }\n }\n collectLists(fields)\n\n const hasTabsField = fields.some((f) => f.type === 'tabs')\n const tabsField = fields.find((f) => f.type === 'tabs')\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n return { relFields, listFieldsWithNested, hasTabsField, firstTabName, tabFieldNames }\n}\n\n// ============================================================================\n// Per-group JSX generation\n// ============================================================================\n\nfunction buildGroupFieldsJSX(\n group: CardGroup,\n analysis: GroupAnalysis,\n skipLabel: boolean\n): string {\n const indent = ' '\n return group.fields\n .map((f) => {\n if (f.type === 'tabs' && f.tabs) {\n const tabsList = f.tabs\n .map((t) => ` <TabsTrigger value=\"${t.name}\">${t.label}</TabsTrigger>`)\n .join('\\n')\n const tabsContent = f.tabs\n .map((t) => {\n const tabFields = (t.fields || [])\n .map((tf) => generateFieldJSX(tf, ' '))\n .join('\\n')\n return ` <TabsContent value=\"${t.name}\" className=\"space-y-6\">\n${tabFields}\n </TabsContent>`\n })\n .join('\\n')\n return `${indent}<Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n${indent}</Tabs>`\n }\n if (analysis.tabFieldNames.has(f.name)) return ''\n return generateFieldJSX(f, indent, { skipLabel })\n })\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction buildGroupRelState(analysis: GroupAnalysis): string {\n return analysis.relFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return ` const [${f.name}Open, set${toPascalCase(f.name)}Open] = React.useState(false)\n const { data: ${f.relationship}Data } = use${relPlural}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n}\n\nfunction buildGroupFieldArrayHooks(analysis: GroupAnalysis): string {\n return analysis.listFieldsWithNested\n .map((field) => {\n const pascalFieldName = toPascalCase(field.name)\n return ` const [${field.name}Expanded, set${pascalFieldName}Expanded] = React.useState<string | undefined>(undefined)\n const ${field.name}FieldArray = useFieldArray({\n control: form.control,\n name: '${field.name}'\n })`\n })\n .join('\\n')\n}\n\n// ============================================================================\n// Card component generation\n// ============================================================================\n\nfunction generateCardComponent(\n group: CardGroup,\n schema: Schema,\n analysis: GroupAnalysis\n): string {\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n const zodFields = buildZodFields(group.flatFields)\n const defaultValues = buildDefaultValues(group.flatFields)\n const isSingleField = group.fields.length === 1 && group.title === (group.fields[0].label || group.fields[0].name)\n const fieldsJSX = buildGroupFieldsJSX(group, analysis, isSingleField)\n const relState = buildGroupRelState(analysis)\n const fieldArrayHooks = buildGroupFieldArrayHooks(analysis)\n\n const descriptionLine = group.description\n ? `\\n <CardDescription>${group.description}</CardDescription>`\n : ''\n\n return `const ${group.varPrefix}Schema = z.object({\n${zodFields}\n})\n\nfunction ${group.componentName}({ initialData }: { initialData?: ${Singular}Data | null }) {\n const queryClient = useQueryClient()${analysis.hasTabsField ? `\\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${analysis.firstTabName}' })` : ''}${relState ? `\\n${relState}` : ''}\n\n const mutation = useMutation({\n mutationFn: (data: Upsert${Singular}Input) => upsert${Singular}(data),\n onSuccess: () => {\n toast.success('${group.title} saved')\n queryClient.invalidateQueries({ queryKey: ['${schema.name}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to save')\n }\n })\n\n const isPending = mutation.isPending\n\n const form = useForm<z.infer<typeof ${group.varPrefix}Schema>>({\n resolver: zodResolver(${group.varPrefix}Schema),\n defaultValues: {\n${defaultValues}\n }\n })\n${fieldArrayHooks ? `\\n${fieldArrayHooks}\\n` : ''}\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit((values) => {\n const cleaned = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [key, value === undefined ? '' : value])\n )\n mutation.mutate(cleaned as Upsert${Singular}Input)\n })}>\n <Card className=\"material-sm!\">\n <CardHeader>\n <CardTitle>${group.title}</CardTitle>${descriptionLine}\n </CardHeader>\n <CardContent className=\"space-y-6\">\n${fieldsJSX}\n </CardContent>\n <CardFooter>${group.hint ? `\\n <p className=\"text-sm text-muted-foreground\">${group.hint}</p>` : ''}\n <Button type=\"submit\" disabled={isPending} size=\"sm\" className=\"ml-auto\">\n {isPending ? 'Saving...' : 'Save'}\n </Button>\n </CardFooter>\n </Card>\n </form>\n </Form>\n )\n}`\n}\n\n// ============================================================================\n// Main generator\n// ============================================================================\n\nexport function generateSingleForm(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): FormGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const formFilePath = path.join(entityDir, `${schema.name}-form.tsx`)\n\n if (fs.existsSync(formFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n // Filter out auto-generated fields\n const allFormFields = schema.fields.filter(\n (f) => !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt'\n )\n\n // Parse into card groups\n const cardGroups = parseCardGroups(allFormFields, schema.label)\n\n // --- Global field analysis for imports ---\n const hasBoolean = hasFieldType(schema.fields, 'boolean')\n const hasImage = hasFieldType(schema.fields, 'image')\n const hasVideo = hasFieldType(schema.fields, 'video')\n const hasMedia = hasFieldType(schema.fields, 'media')\n const hasIcon = hasFieldType(schema.fields, 'icon')\n const hasIconPostfix = hasIconUsage(schema.fields)\n const hasDate = hasFieldType(schema.fields, 'date')\n const hasSelect = hasFieldType(schema.fields, 'select')\n const hasMarkdown = hasFieldType(schema.fields, 'markdown')\n const hasRichtext = hasFieldType(schema.fields, 'richtext')\n const hasTextarea = hasFieldType(schema.fields, 'text')\n const hasSeparator = hasFieldType(schema.fields, 'separator')\n const hasRelationship = hasFieldType(schema.fields, 'relationship')\n const hasTabsField = schema.fields.some((f) => f.type === 'tabs')\n const flatFields = flattenFields(allFormFields)\n const hasList = hasFieldType(schema.fields, 'list')\n const hasNestedList = cardGroups.some((g) => analyzeGroup(g.fields).listFieldsWithNested.length > 0)\n const hasSimpleList =\n hasList && flatFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n\n // Global relationship hooks for imports\n const allRelFields: SchemaField[] = []\n for (const g of cardGroups) {\n const a = analyzeGroup(g.fields)\n for (const rf of a.relFields) {\n if (!allRelFields.some((e) => e.relationship === rf.relationship)) {\n allRelFields.push(rf)\n }\n }\n }\n\n const needsReact = allRelFields.length > 0 || hasNestedList\n\n // --- Build imports ---\n const uiImports = buildUiImports({\n hasBoolean,\n hasTextarea,\n hasImage,\n hasVideo,\n hasMedia,\n hasIcon,\n hasIconPostfix,\n hasDate,\n hasMarkdown,\n hasRichtext,\n hasSeparator,\n hasSelect,\n hasTabsField,\n hasRelationship,\n hasSimpleList,\n hasNestedList\n })\n\n // Add Card imports\n uiImports.push(`import {\n Card,\n CardContent,\n CardDescription,\n CardFooter,\n CardHeader,\n CardTitle\n} from '@cms/components/ui/card'`)\n\n // Lucide icons\n const lucideIcons: string[] = []\n if (hasRelationship) lucideIcons.push('Check', 'ChevronsUpDown')\n if (hasNestedList) {\n if (!lucideIcons.includes('Plus')) lucideIcons.push('Plus')\n if (!lucideIcons.includes('X')) lucideIcons.push('X')\n }\n\n // Relationship hook imports\n const relHookImports = allRelFields\n .map((f) => {\n const relPlural = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relPlural} } from '@cms/hooks/use-${f.relationship}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // --- Generate per-group card components ---\n const cardComponents = cardGroups.map((group) => {\n const analysis = analyzeGroup(group.fields)\n return generateCardComponent(group, schema, analysis)\n })\n\n // --- Generate parent component ---\n const cardRenders = cardGroups\n .map((g) => ` <${g.componentName} initialData={initialData} />`)\n .join('\\n')\n\n // --- Assemble file ---\n const content = `'use client'\n${needsReact ? \"\\nimport * as React from 'react'\" : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideIcons.length > 0 ? `\\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\nimport {${hasNestedList ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod/v3'${hasTabsField ? \"\\nimport { useQueryState } from 'nuqs'\" : ''}${hasRelationship ? \"\\nimport { cn } from '@cms/utils/cn'\" : ''}\n${relHookImports ? `${relHookImports}\\n` : ''}${uiImports.join('\\n')}\nimport type {\n ${Singular}Data,\n Upsert${Singular}Input\n} from '@cms/actions/${schema.name}'\nimport { upsert${Singular} } from '@cms/actions/${schema.name}'\n\n${cardComponents.join('\\n\\n')}\n\ninterface ${Singular}FormProps {\n initialData?: ${Singular}Data | null\n}\n\nexport function ${Singular}Form({ initialData }: ${Singular}FormProps) {\n return (\n <div className=\"space-y-6\">\n${cardRenders}\n </div>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, `${schema.name}-form.tsx`)]\n }\n}\n","/**\n * Generator 3: React Query hook — cms/hooks/use-<n>.ts\n * Generates client-side data fetching hooks wrapping server actions\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { flattenFields } from '../core/field-helpers/index.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, pluralize } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface HookGeneratorResult {\n files: string[]\n hookName: string\n}\n\n/**\n * Generate React Query hook for an entity — writes to cms/hooks/use-<n>.ts\n */\nexport function generateHook(\n schema: Schema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions = {}\n): HookGeneratorResult {\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(cwd, hooksDir, hookFileName)\n\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n\n // Check if schema has a slug field\n const dbFields = flattenFields(schema.fields)\n const hasSlugField = dbFields.some((f) => f.name === 'slug')\n const hasHtmlOutput = dbFields.some(\n (f) => (f.type === 'richtext' || f.type === 'markdown') && f.output === 'html'\n )\n\n // Check for existing file\n if (fs.existsSync(hookFilePath) && !options.force) {\n return { files: [], hookName: `use${Plural}` }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // --- Build imports from actions ---\n const actionImports: string[] = [`get${Plural}`, `get${Singular}ById`]\n if (hasSlugField) actionImports.push(`get${Singular}BySlug`)\n if (hasFilters) {\n for (const filter of schema.filters!) {\n actionImports.push(`getDistinct${Plural}${toPascalCase(filter.field)}`)\n }\n }\n const typeImports = [\n `type ${Singular}Data`,\n ...(hasHtmlOutput && hasSlugField ? [`type ${Singular}DisplayData`] : []),\n `type ${Plural}Response`,\n `type Get${Plural}Filters`\n ]\n\n // --- Build filter parameters ---\n const filterParams = hasFilters\n ? schema.filters!.map((f) => `${f.field}?: string`).join(', ')\n : ''\n const allParams = filterParams ? `search?: string, ${filterParams}` : 'search?: string'\n\n // --- Build query key with all filter params ---\n const queryKeyParts = hasFilters\n ? [\"search ?? ''\", ...schema.filters!.map((f) => `${f.field} ?? ''`)].join(', ')\n : \"search ?? ''\"\n\n // --- Build filters object in queryFn ---\n const filtersBody = hasFilters\n ? `const filters: Get${Plural}Filters = {}\n if (search) filters.search = search\n${schema.filters!.map((f) => ` if (${f.field}) filters.${f.field} = ${f.field}`).join('\\n')}\n return get${Plural}(Object.keys(filters).length > 0 ? filters : undefined)`\n : `const filters: Get${Plural}Filters | undefined = search ? { search } : undefined\n return get${Plural}(filters)`\n\n // --- Singular hook ---\n const singularHook = `\nexport function use${Singular}(id: number | null | undefined): UseQueryResult<${Singular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singular}', id],\n queryFn: () => (id ? get${Singular}ById(id) : Promise.resolve(null)),\n enabled: !!id,\n staleTime: 0\n })\n}`\n\n // --- Slug hook ---\n const slugReturnType = hasHtmlOutput ? `${Singular}DisplayData` : `${Singular}Data`\n const slugHook = hasSlugField\n ? `\n\nexport function use${Singular}BySlug(slug: string | null | undefined): UseQueryResult<${slugReturnType} | null, Error> {\n return useQuery({\n queryKey: ['${singular}', 'slug', slug],\n queryFn: () => (slug ? get${Singular}BySlug(slug) : Promise.resolve(null)),\n enabled: !!slug,\n staleTime: 0\n })\n}`\n : ''\n\n // --- Distinct filter hooks ---\n const distinctHooks = hasFilters\n ? schema\n .filters!.map(\n (filter) => `\n\nexport function use${Plural}Distinct${toPascalCase(filter.field)}(): UseQueryResult<string[], Error> {\n return useQuery({\n queryKey: ['${plural}', 'distinct', '${filter.field}'],\n queryFn: () => getDistinct${Plural}${toPascalCase(filter.field)}()\n })\n}`\n )\n .join('')\n : ''\n\n // --- Assemble file ---\n const content = `import {\n ${[...actionImports, ...typeImports].join(',\\n ')}\n} from '@cms/actions/${schema.name}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${Plural}(\n ${allParams ? `${allParams},` : ''}\n options?: { enabled?: boolean }\n): UseQueryResult<${Plural}Response, Error> {\n return useQuery({\n queryKey: ['${plural}', ${queryKeyParts}],\n queryFn: () => {\n ${filtersBody}\n },\n enabled: options?.enabled ?? true,\n refetchOnMount: 'always'\n })\n}\n${singularHook}${slugHook}${distinctHooks}\n`\n\n // Write file\n const dir = path.dirname(hookFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n return {\n files: [path.join(hooksDir, hookFileName)],\n hookName: `use${Plural}`\n }\n}\n\n/**\n * Generate React Query hook for a single (singleton) schema.\n * Only useXxx() query — no list, slug, or filter hooks.\n */\nexport function generateSingleHook(\n schema: Schema,\n cwd: string,\n hooksDir: string,\n options: GeneratorOptions = {}\n): HookGeneratorResult {\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(cwd, hooksDir, hookFileName)\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n\n if (fs.existsSync(hookFilePath) && !options.force) {\n return { files: [], hookName: `use${Singular}` }\n }\n\n const content = `import {\n get${Singular},\n type ${Singular}Data\n} from '@cms/actions/${schema.name}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${Singular}(): UseQueryResult<${Singular}Data | null, Error> {\n return useQuery({\n queryKey: ['${schema.name}'],\n queryFn: () => get${Singular}(),\n staleTime: 0\n })\n}\n`\n\n const dir = path.dirname(hookFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n return {\n files: [path.join(hooksDir, hookFileName)],\n hookName: `use${Singular}`\n }\n}\n","/**\n * Generator 11: Navigation — append to cms/data/navigation.ts\n * Parses existing navigation file and inserts new entity entry.\n * Uses flat `group` property for sidebar grouping (no nested children).\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface NavItem {\n label: string\n href: string\n icon?: string\n group?: string\n}\n\n// ============================================================================\n// Parser\n// ============================================================================\n\n/**\n * Parse existing navigation.ts and extract nav items + icon imports\n */\nfunction parseNavigationFile(content: string): { items: NavItem[]; iconImports: string[] } {\n const iconImportMatch = content.match(/import\\s*\\{([^}]+)\\}\\s*from\\s*['\"]lucide-react['\"]/)\n const iconImports: string[] = iconImportMatch\n ? iconImportMatch[1]\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s && s !== 'LucideIcon')\n : []\n\n const arrayBlock = extractTopLevelArray(content)\n if (!arrayBlock) return { items: [], iconImports }\n\n const items = parseItemsBlock(arrayBlock)\n return { items, iconImports }\n}\n\n/**\n * Find the cmsNavigation array and extract its content using bracket counting\n */\nfunction extractTopLevelArray(content: string): string | null {\n const marker = content.indexOf('cmsNavigation')\n if (marker === -1) return null\n\n const eqSign = content.indexOf('=', marker)\n if (eqSign === -1) return null\n const openBracket = content.indexOf('[', eqSign)\n if (openBracket === -1) return null\n\n let depth = 0\n for (let i = openBracket; i < content.length; i++) {\n if (content[i] === '[') depth++\n if (content[i] === ']') depth--\n if (depth === 0) {\n return content.slice(openBracket + 1, i)\n }\n }\n return null\n}\n\nfunction parseItemsBlock(block: string): NavItem[] {\n const items: NavItem[] = []\n let depth = 0\n let current = ''\n let inObj = false\n\n for (const char of block) {\n if (char === '{') {\n if (depth === 0) inObj = true\n depth++\n current += char\n } else if (char === '}') {\n depth--\n current += char\n if (depth === 0 && inObj) {\n const item = parseSingleItem(current)\n if (item) items.push(item)\n current = ''\n inObj = false\n }\n } else if (inObj) {\n current += char\n }\n }\n\n return items\n}\n\nfunction parseSingleItem(str: string): NavItem | null {\n const labelMatch = str.match(/label:\\s*['\"]([^'\"]+)['\"]/)\n const hrefMatch = str.match(/href:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = str.match(/icon:\\s*(\\w+)/)\n const groupMatch = str.match(/group:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!labelMatch || !hrefMatch) return null\n\n const item: NavItem = {\n label: labelMatch[1],\n href: hrefMatch[1]\n }\n if (iconMatch) item.icon = iconMatch[1]\n if (groupMatch) item.group = groupMatch[1]\n\n return item\n}\n\n// ============================================================================\n// Code Generator\n// ============================================================================\n\nfunction generateNavigationCode(items: NavItem[], iconImports: string[]): string {\n const lines: string[] = []\n\n lines.push(\"import type { LucideIcon } from 'lucide-react'\")\n lines.push(`import { ${iconImports.join(', ')} } from 'lucide-react'`)\n lines.push('')\n lines.push('export interface CmsNavigationItem {')\n lines.push(' label: string')\n lines.push(' href: string')\n lines.push(' icon?: LucideIcon')\n lines.push(' group?: string')\n lines.push('}')\n lines.push('')\n lines.push('export const cmsNavigation: CmsNavigationItem[] = [')\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n appendItem(lines, item, isLast)\n }\n\n lines.push(']')\n lines.push('')\n\n return lines.join('\\n')\n}\n\nfunction appendItem(lines: string[], item: NavItem, isLast: boolean): void {\n lines.push(' {')\n lines.push(` label: '${item.label}',`)\n\n const hasMore = item.icon != null || item.group != null\n lines.push(` href: '${item.href}'${hasMore ? ',' : ''}`)\n\n if (item.icon && item.group) {\n lines.push(` icon: ${item.icon},`)\n lines.push(` group: '${item.group}'`)\n } else if (item.icon) {\n lines.push(` icon: ${item.icon}`)\n } else if (item.group) {\n lines.push(` group: '${item.group}'`)\n }\n\n lines.push(` }${isLast ? '' : ','}`)\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface NavigationGeneratorResult {\n files: string[]\n}\n\n/**\n * Update cms/data/navigation.ts to include new entity nav item\n */\nexport function updateNavigation(\n schema: Schema,\n cwd: string,\n cmsDir: string,\n options: GeneratorOptions = {}\n): NavigationGeneratorResult {\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n\n // Settings lives in the sidebar footer, not in navigation\n if (schema.name === 'settings') {\n return { files: [] }\n }\n\n // Parse existing navigation\n let items: NavItem[] = []\n let iconImports: string[] = []\n\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const parsed = parseNavigationFile(content)\n items = parsed.items\n iconImports = parsed.iconImports\n }\n\n const entityHref = `/cms/${schema.name}`\n\n const newItem: NavItem = {\n label: schema.label,\n href: entityHref,\n icon: schema.icon\n }\n\n // If schema has a navGroup, set the group property\n if (schema.navGroup) {\n newItem.group = schema.navGroup.label\n }\n\n // Check if item already exists\n const existingIndex = items.findIndex((item) => item.href === entityHref)\n\n if (existingIndex >= 0) {\n if (options.force) {\n items[existingIndex] = newItem\n } else {\n return { files: [] }\n }\n } else {\n items.push(newItem)\n }\n\n // Reorganize: Dashboard first, then ungrouped alphabetical, then grouped alphabetical\n const dashboard = items.find((item) => item.href === '/cms')\n const others = items.filter((item) => item.href !== '/cms')\n others.sort((a, b) => {\n // Ungrouped items first, then by group name, then by label\n if (!a.group && b.group) return -1\n if (a.group && !b.group) return 1\n if (a.group && b.group && a.group !== b.group) return a.group.localeCompare(b.group)\n return a.label.localeCompare(b.label)\n })\n\n items = [...(dashboard ? [dashboard] : []), ...others]\n\n // Add icon import if needed\n if (schema.icon && !iconImports.includes(schema.icon)) {\n iconImports.push(schema.icon)\n }\n iconImports.sort()\n\n // Write updated file\n const dir = path.dirname(navFilePath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n\n const code = generateNavigationCode(items, iconImports)\n fs.writeFileSync(navFilePath, code, 'utf-8')\n\n return {\n files: [path.join(cmsDir, 'data', 'navigation.ts')]\n }\n}\n","/**\n * Generator 7: Page (server) — (authenticated)/<n>/page.tsx\n * Generates the server page component that renders columns + page content\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, pluralize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface PageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate server page component for entity list view\n */\nexport function generatePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): PageGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const pageFilePath = path.join(entityDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const plural = pluralize(schema.name)\n const Plural = toPascalCase(plural)\n const kebabPlural = toKebabCase(plural)\n\n const content = `import * as React from 'react'\nimport { columns } from './columns'\nimport { ${Plural}PageContent } from './${kebabPlural}-page-content'\n\nexport default function ${Plural}Page() {\n return (\n <React.Suspense\n fallback={\n <div className=\"flex items-center justify-center h-48\">\n <div className=\"text-muted-foreground\">Loading ${schema.label}...</div>\n </div>\n }\n >\n <div className=\"flex flex-col\">\n <${Plural}PageContent columns={columns} />\n </div>\n </React.Suspense>\n )\n}\n`\n\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'page.tsx')]\n }\n}\n","/**\n * Generator 6: Page content — (authenticated)/<n>/<n>-page-content.tsx\n * Generates client component with search, filters, bulk delete, and table\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize, pluralize, singularizeLabel, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface PageContentGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate page content component for entity list view\n */\nexport function generatePageContent(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): PageContentGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const fileName = `${toKebabCase(plural)}-page-content.tsx`\n const filePath = path.join(entityDir, fileName)\n\n if (fs.existsSync(filePath) && !options.force) {\n return { files: [] }\n }\n\n const hasCreate = schema.actions?.create ?? false\n const hasDelete = schema.actions?.delete ?? false\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // --- Lucide icons ---\n const lucideIcons: string[] = ['ChevronLeft', 'Search', 'CornerDownLeft']\n if (hasCreate) lucideIcons.push('Plus')\n if (hasDelete) lucideIcons.push('Trash2')\n if (hasFilters) lucideIcons.push('Check', 'ChevronsUpDown')\n\n // --- Build imports ---\n let imports = `'use client'\n\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { ${lucideIcons.join(', ')} } from 'lucide-react'\n${hasCreate ? \"import Link from 'next/link'\\n\" : ''}import { useRouter } from 'next/navigation'\nimport { parseAsString${hasDelete ? ', parseAsArrayOf, parseAsInteger' : ''}, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\n${hasDelete ? \"import { toast } from 'sonner'\\n\" : ''}import { PageHeader } from '@cms/components/shared/page-header'\nimport { Button } from '@cms/components/ui/button'\nimport { Input } from '@cms/components/ui/input'\n`\n\n if (hasDelete) {\n imports += `import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger\n} from '@cms/components/ui/alert-dialog'\n`\n }\n\n if (hasFilters) {\n imports += `import {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList\n} from '@cms/components/ui/command'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger\n} from '@cms/components/ui/popover'\nimport { cn } from '@cms/utils/cn'\n`\n // Filter hooks\n const filterHooks = schema\n .filters!.map((f) => `use${Plural}Distinct${toPascalCase(f.field)}`)\n .join(', ')\n imports += `import { ${filterHooks} } from '@cms/hooks/use-${schema.name}'\\n`\n }\n\n imports += `import type { ${Singular}Data } from '@cms/actions/${schema.name}'\n${hasDelete ? `import { deleteBulk${Plural} } from '@cms/actions/${schema.name}'\\n` : ''}import { ${Plural}Table } from './${toKebabCase(plural)}-table'\n`\n\n // --- SearchButton component ---\n const searchButton = `function SearchButton() {\n const { pending } = useFormStatus()\n return (\n <Button type=\"submit\" variant=\"outline\" size=\"default\" disabled={pending}>\n {pending ? 'Searching...' : 'Search'}\n </Button>\n )\n}\n\n`\n\n // --- Filter state ---\n const filterLogic = hasFilters\n ? schema\n .filters!.map(\n (f) =>\n ` const [${f.field}, set${toPascalCase(f.field)}] = useQueryState('${f.field}', parseAsString.withDefault(''))\n const { data: ${f.field}Options } = use${Plural}Distinct${toPascalCase(f.field)}()\n const [${f.field}ComboboxOpen, set${toPascalCase(f.field)}ComboboxOpen] = React.useState(false)`\n )\n .join('\\n')\n : ''\n\n // --- Search logic ---\n const searchLogic = ` const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n\n const searchAction = React.useCallback(async (formData: FormData) => {\n const value = formData.get('search') as string\n React.startTransition(() => {\n setSearch(value || null)\n })\n }, [setSearch])\n${filterLogic ? `\\n${filterLogic}` : ''}`\n\n // --- Delete logic ---\n const deleteLogic = hasDelete\n ? `\n const [selectedIds, setSelectedIds] = useQueryState(\n 'selected',\n parseAsArrayOf(parseAsInteger).withDefault([])\n )\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false)\n const [isPending, startTransition] = React.useTransition()\n\n const handleBulkDelete = () => {\n startTransition(async () => {\n try {\n const result = await deleteBulk${Plural}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} ${singular}\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${plural}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n`\n : ''\n\n // --- Filter dropdowns ---\n const _filterDropdowns = hasFilters\n ? schema\n .filters!.map(\n (\n f\n ) => ` <Popover open={${f.field}ComboboxOpen} onOpenChange={set${toPascalCase(f.field)}ComboboxOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={${f.field}ComboboxOpen}\n className=\"w-[200px] justify-between\"\n >\n {${f.field} || '${f.label}'}\n <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[200px] p-0\">\n <Command>\n <CommandInput placeholder=\"Search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n key=\"all\"\n value=\"\"\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(f.field)}('')\n })\n set${toPascalCase(f.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 size-4',\n ${f.field} === '' ? 'opacity-100' : 'opacity-0'\n )}\n />\n All ${f.label}\n </CommandItem>\n {${f.field}Options?.map((option) => (\n <CommandItem\n key={option}\n value={option}\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(f.field)}(option)\n })\n set${toPascalCase(f.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 size-4',\n ${f.field} === option ? 'opacity-100' : 'opacity-0'\n )}\n />\n {option}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>`\n )\n .join('\\n')\n : ''\n\n // --- Search input ---\n const searchInput = `<form action={searchAction} className=\"flex items-center gap-2 relative\">\n <Search className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n key={search}\n name=\"search\"\n placeholder=\"Search ${schema.label.toLowerCase()}...\"\n defaultValue={search}\n className=\"w-64 pl-9 bg-white rounded-lg\"\n />\n <CornerDownLeft className=\"text-muted-foreground/70 pointer-events-none absolute top-1/2 right-3 size-4 -translate-y-1/2\" />\n </form>`\n\n // --- Delete button ---\n const deleteButton = hasDelete\n ? ` {selectedIds.length > 0 && (\n <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n <AlertDialogTrigger asChild>\n <Button variant=\"destructive\" size=\"default\">\n <Trash2 className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? '${singular}' : '${plural}'}\n </Button>\n </AlertDialogTrigger>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Are you sure?</AlertDialogTitle>\n <AlertDialogDescription>\n This action cannot be undone. This will permanently delete {selectedIds.length}{' '}\n {selectedIds.length === 1 ? '${singular}' : '${plural}'}.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={isPending}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={(e) => {\n e.preventDefault()\n handleBulkDelete()\n }}\n disabled={isPending}\n className=\"bg-destructive text-destructive-foreground hover:bg-destructive/90\"\n >\n {isPending ? 'Deleting...' : 'Delete'}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}`\n : ''\n\n // --- Create button ---\n const createButton = hasCreate\n ? ` <Button asChild>\n <Link href=\"/cms/${schema.name}/new\">\n <Plus className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Create ${singularizeLabel(schema.label)}\n </Link>\n </Button>`\n : ''\n\n // --- Table props ---\n const filterPropsStr = hasFilters\n ? schema.filters!.map((f) => `${f.field}={${f.field}}`).join(' ')\n : ''\n const allTableProps = filterPropsStr ? `search={search} ${filterPropsStr}` : 'search={search}'\n const tableProps = hasDelete\n ? `columns={columns} selectedIds={selectedIds} setSelectedIds={setSelectedIds} ${allTableProps}`\n : `columns={columns} selectedIds={[]} setSelectedIds={() => {}} ${allTableProps}`\n\n // --- Assemble file ---\n const content = `${imports}\n${searchButton}interface ${Plural}PageContentProps<TValue> {\n columns: ColumnDef<${Singular}Data, TValue>[]\n}\n\nexport function ${Plural}PageContent<TValue>({\n columns\n}: ${Plural}PageContentProps<TValue>) {\n const router = useRouter()\n const queryClient = useQueryClient()\n${searchLogic}${deleteLogic}\n return (\n <>\n <PageHeader title=\"${schema.label}\" back={<Button variant=\"ghost\" size=\"icon\" onClick={() => router.back()}><ChevronLeft /></Button>} search={${searchInput}} actions={<div className=\"flex items-center gap-2\">${deleteButton} ${createButton}</div>} />\n <main className=\"space-y-6 p-6\">\n <${Plural}Table ${tableProps} />\n </main>\n </>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, fileName)]\n }\n}\n","/**\n * Generator: Single page — (authenticated)/<n>/page.tsx\n * Server component that fetches the singleton record and renders the form.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, singularize } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface SinglePageGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate server page for a single (singleton) schema.\n * Calls getXxx() and renders XxxForm with initialData (null on first visit).\n */\nexport function generateSinglePage(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): SinglePageGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const pageFilePath = path.join(entityDir, 'page.tsx')\n\n if (fs.existsSync(pageFilePath) && !options.force) {\n return { files: [] }\n }\n\n const singular = singularize(schema.name)\n const Singular = toPascalCase(singular)\n const PageName = toPascalCase(schema.name)\n\n const content = `import { get${Singular} } from '@cms/actions/${schema.name}'\nimport { PageHeader } from '@cms/components/shared/page-header'\nimport { ${Singular}Form } from './${schema.name}-form'\nimport { connection } from 'next/server'\n\nexport default async function ${PageName}Page() {\n await connection()\n const data = await get${Singular}()\n\n return (\n <>\n <PageHeader title=\"${schema.label}\" />\n <main className=\"container mx-auto max-w-5xl p-6 pb-20\">\n <${Singular}Form initialData={data} />\n </main>\n </>\n )\n}\n`\n\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, 'page.tsx')]\n }\n}\n","/**\n * Generator 5: Table component — (authenticated)/<n>/<n>-table.tsx\n * Generates data table with pagination, sorting, reorder, and row selection\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { toPascalCase, toCamelCase, singularize, pluralize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport interface TableGeneratorResult {\n files: string[]\n}\n\n/**\n * Generate table component for entity list view\n */\nexport function generateTable(\n schema: Schema,\n cwd: string,\n pagesDir: string,\n options: GeneratorOptions = {}\n): TableGeneratorResult {\n const entityDir = path.join(cwd, pagesDir, schema.name)\n const singular = singularize(schema.name)\n const plural = pluralize(schema.name)\n const Singular = toPascalCase(singular)\n const Plural = toPascalCase(plural)\n const camelPlural = toCamelCase(plural)\n const camelSingular = toCamelCase(singular)\n const tableFileName = `${toKebabCase(plural)}-table.tsx`\n const tableFilePath = path.join(entityDir, tableFileName)\n\n if (fs.existsSync(tableFilePath) && !options.force) {\n return { files: [] }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n const filterProps = hasFilters\n ? schema.filters!.map((f) => `${f.field}?: string`).join('\\n ')\n : ''\n const allFilterProps = filterProps ? `\\n ${filterProps}` : ''\n const filterParams = hasFilters ? schema.filters!.map((f) => f.field).join(', ') : ''\n const allParams = filterParams ? `search, ${filterParams}` : 'search'\n\n const content = `'use client'\n\nimport {\n type ColumnDef,\n type ColumnFiltersState,\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n getSortedRowModel,\n type SortingState,\n useReactTable,\n type VisibilityState\n} from '@tanstack/react-table'\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { Button } from '@cms/components/ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue\n} from '@cms/components/ui/select'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '@cms/components/ui/table'\nimport { use${Plural} } from '@cms/hooks/use-${schema.name}'\nimport { bulkUpdate${Plural}SortOrder } from '@cms/actions/${schema.name}'\nimport type { ${Singular}Data } from '@cms/actions/${schema.name}'\nimport '@cms/types/table-meta'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ArrowUpDown, Save } from 'lucide-react'\nimport { toast } from 'sonner'\n\nconst PAGE_SIZE_OPTIONS = [\n { value: '10', label: '10' },\n { value: '20', label: '20' },\n { value: '50', label: '50' },\n { value: '100', label: '100' },\n { value: 'all', label: 'All' }\n]\n\ninterface ${Plural}TableProps<TValue> {\n columns: ColumnDef<${Singular}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string${allFilterProps}\n}\n\nexport function ${Plural}Table<TValue>({ columns, selectedIds, setSelectedIds, ${allParams} }: ${Plural}TableProps<TValue>) {\n const { data, error, isPending } = use${Plural}(${allParams})\n const queryClient = useQueryClient()\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})\n const [pageIndex, setPageIndex] = useQueryState('page', parseAsInteger.withDefault(0))\n const [pageSize, setPageSize] = useQueryState('size', parseAsInteger.withDefault(20))\n\n // Reorder mode state\n const [reorderMode, setReorderMode] = React.useState(false)\n const [localData, setLocalData] = React.useState<${Singular}Data[]>([])\n const [hasChanges, setHasChanges] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n\n // Sync local data when server data changes\n React.useEffect(() => {\n if (data?.${camelPlural}) {\n setLocalData([...data.${camelPlural}])\n setHasChanges(false)\n }\n }, [data?.${camelPlural}])\n\n // Handle local row move (client-side only)\n const handleMoveRow = React.useCallback((id: number, direction: 'up' | 'down') => {\n setLocalData((prev) => {\n const index = prev.findIndex((item) => item.id === id)\n if (index === -1) return prev\n\n const newIndex = direction === 'up' ? index - 1 : index + 1\n if (newIndex < 0 || newIndex >= prev.length) return prev\n\n const newData = [...prev]\n const [removed] = newData.splice(index, 1)\n newData.splice(newIndex, 0, removed)\n\n return newData\n })\n setHasChanges(true)\n }, [])\n\n // Save all sort order changes to the database\n const handleSave = React.useCallback(async () => {\n if (!hasChanges) return\n\n setIsSaving(true)\n try {\n const updates = localData.map((item, index) => ({\n id: item.id as number,\n sortOrder: index\n }))\n\n const result = await bulkUpdate${Plural}SortOrder(updates)\n\n if (result.success) {\n toast.success('Sort order saved successfully')\n queryClient.refetchQueries({ queryKey: ['${plural}'] })\n setHasChanges(false)\n setReorderMode(false)\n } else {\n toast.error(result.error || 'Failed to save sort order')\n }\n } catch (error) {\n toast.error('An error occurred while saving')\n console.error(error)\n } finally {\n setIsSaving(false)\n }\n }, [hasChanges, localData, queryClient])\n\n // Cancel reorder mode and reset changes\n const handleCancelReorder = React.useCallback(() => {\n if (data?.${camelPlural}) {\n setLocalData([...data.${camelPlural}])\n }\n setHasChanges(false)\n setReorderMode(false)\n }, [data?.${camelPlural}])\n\n // Use local data when in reorder mode, otherwise use server data\n const tableData = reorderMode ? localData : (data?.${camelPlural} ?? [])\n\n // Convert selectedIds array to rowSelection object format\n const rowSelection = React.useMemo(() => {\n const selection: Record<string, boolean> = {}\n const ${camelPlural} = data?.${camelPlural} ?? []\n ${camelPlural}.forEach((${camelSingular}, index) => {\n if (selectedIds.includes(${camelSingular}.id as number)) {\n selection[index.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.${camelPlural}])\n\n // Handle row selection changes\n const handleRowSelectionChange = React.useCallback(\n (updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)) => {\n const ${camelPlural} = data?.${camelPlural} ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n\n const newSelectedIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => ${camelPlural}[Number.parseInt(key)]?.id as number)\n .filter(Boolean)\n\n setSelectedIds(newSelectedIds)\n },\n [data?.${camelPlural}, rowSelection, setSelectedIds]\n )\n\n // Determine effective page size (handle 'all' case)\n const effectivePageSize = pageSize === -1 ? Number.MAX_SAFE_INTEGER : pageSize\n\n const handlePageSizeChange = React.useCallback((value: string) => {\n React.startTransition(() => {\n if (value === 'all') {\n setPageSize(-1)\n } else {\n setPageSize(Number(value))\n }\n setPageIndex(0)\n })\n }, [setPageSize, setPageIndex])\n\n const handlePaginationChange = React.useCallback(\n (updater: { pageIndex: number; pageSize: number } | ((old: { pageIndex: number; pageSize: number }) => { pageIndex: number; pageSize: number })) => {\n const currentPagination = { pageIndex, pageSize: effectivePageSize }\n const newPagination = typeof updater === 'function' ? updater(currentPagination) : updater\n React.startTransition(() => {\n setPageIndex(newPagination.pageIndex)\n })\n },\n [pageIndex, effectivePageSize, setPageIndex]\n )\n\n const table = useReactTable({\n data: tableData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onSortingChange: setSorting,\n getSortedRowModel: getSortedRowModel(),\n onColumnFiltersChange: setColumnFilters,\n getFilteredRowModel: getFilteredRowModel(),\n onColumnVisibilityChange: setColumnVisibility,\n onRowSelectionChange: handleRowSelectionChange,\n onPaginationChange: handlePaginationChange,\n meta: {\n reorderMode,\n onMoveRow: handleMoveRow\n },\n state: {\n sorting,\n columnFilters,\n columnVisibility,\n rowSelection,\n pagination: {\n pageIndex,\n pageSize: effectivePageSize\n }\n }\n })\n\n return (\n <div className=\"space-y-6\">\n {/* Reorder controls */}\n <div className=\"flex items-center gap-2\">\n <Button\n variant={reorderMode ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setReorderMode(!reorderMode)}\n disabled={isSaving}\n >\n <ArrowUpDown className=\"size-4 mr-1\" />\n Sort Order\n </Button>\n {reorderMode && (\n <>\n <Button\n variant=\"default\"\n size=\"sm\"\n onClick={handleSave}\n disabled={!hasChanges || isSaving}\n >\n <Save className=\"size-4 mr-1\" />\n {isSaving ? 'Saving...' : 'Save'}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancelReorder}\n disabled={isSaving}\n >\n Cancel\n </Button>\n {hasChanges && (\n <span className=\"text-sm text-muted-foreground\">\n Unsaved changes\n </span>\n )}\n </>\n )}\n </div>\n\n <div className=\"bg-card border overflow-hidden rounded-lg\">\n <Table>\n <TableHeader className=\"bg-secondary\">\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id}>\n {headerGroup.headers.map((header) => {\n return (\n <TableHead key={header.id}>\n {header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n </TableHead>\n )\n })}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {isPending ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n <div className=\"text-muted-foreground\">Loading ${schema.label}...</div>\n </TableCell>\n </TableRow>\n ) : error ? (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n <div className=\"text-destructive\">Error loading ${schema.label}: {error.message}</div>\n </TableCell>\n </TableRow>\n ) : table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n ))}\n </TableRow>\n ))\n ) : (\n <TableRow>\n <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n No ${schema.label} found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">Rows per page</span>\n <Select\n value={pageSize === -1 ? 'all' : String(pageSize)}\n onValueChange={handlePageSizeChange}\n >\n <SelectTrigger className=\"w-[100px] h-8\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {PAGE_SIZE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center space-x-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n Previous\n </Button>\n <div className=\"text-sm text-muted-foreground\">\n Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount() || 1}\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n\n // Write file\n if (!fs.existsSync(entityDir)) {\n fs.mkdirSync(entityDir, { recursive: true })\n }\n fs.writeFileSync(tableFilePath, content, 'utf-8')\n\n return {\n files: [path.join(pagesDir, schema.name, tableFileName)]\n }\n}\n","/**\n * Pipeline orchestrator — runs all 12 entity generation steps in sequence\n */\n\nimport type { BetterstartConfig } from '../config/types.js'\nimport type { GeneratorOptions, Schema } from '../types.js'\nimport { generateActions, generateSingleActions } from './actions/index.js'\nimport { generateCache } from './cache.js'\nimport { generateColumns } from './columns/index.js'\nimport { generateCreatePage } from './create-page.js'\nimport { generateDatabase } from './database.js'\nimport { generateEditPage } from './edit-page.js'\nimport { generateForm, generateSingleForm } from './form/index.js'\nimport { generateHook, generateSingleHook } from './hook.js'\nimport { updateNavigation } from './navigation.js'\nimport { generatePage } from './page.js'\nimport { generatePageContent } from './page-content.js'\nimport { generateSinglePage } from './single-page.js'\nimport { generateTable } from './table.js'\n\nexport interface PipelineResult {\n success: boolean\n files: string[]\n errors: string[]\n}\n\n/**\n * Resolve output directories from config paths\n */\nfunction resolvePaths(config: BetterstartConfig) {\n const cms = config.paths?.cms ?? './cms'\n const pages = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n const schemas = config.paths?.schemas ?? './cms/schemas'\n\n return {\n cmsDir: cms,\n pagesDir: pages,\n schemasDir: schemas,\n dbSchemaDir: `${cms}/db/schema.ts`,\n actionsDir: `${cms}/lib/actions`,\n hooksDir: `${cms}/hooks`\n }\n}\n\n/**\n * Run the full 12-step entity generation pipeline\n */\nexport function runEntityPipeline(\n schema: Schema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): PipelineResult {\n const paths = resolvePaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema',\n run: () => generateDatabase(schema, cwd, paths.dbSchemaDir, options).files\n },\n {\n name: 'Server actions',\n run: () =>\n generateActions(schema, cwd, paths.actionsDir, {\n force: options.force,\n schemasDir: paths.schemasDir\n }).files\n },\n {\n name: 'React Query hook',\n run: () => generateHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Column definitions',\n run: () => generateColumns(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Table component',\n run: () => generateTable(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Page content',\n run: () => generatePageContent(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Page (server)',\n run: () => generatePage(schema, cwd, paths.pagesDir, options).files\n }\n ]\n\n // Steps 8-10 are conditional on schema.actions\n if (schema.actions?.create || schema.actions?.edit) {\n steps.push({\n name: 'Form',\n run: () => generateForm(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n if (schema.actions?.create) {\n steps.push({\n name: 'Create page',\n run: () => generateCreatePage(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n if (schema.actions?.edit) {\n steps.push({\n name: 'Edit page',\n run: () => generateEditPage(schema, cwd, paths.pagesDir, options).files\n })\n }\n\n // Steps 11-12 always run\n steps.push(\n {\n name: 'Navigation',\n run: () => updateNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Cache module',\n run: () => generateCache(schema, cwd, paths.cmsDir, options).files\n }\n )\n\n // Execute each step\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return {\n success: errors.length === 0,\n files,\n errors\n }\n}\n\n/**\n * Run the 7-step single (singleton) generation pipeline\n */\nexport function runSinglePipeline(\n schema: Schema,\n cwd: string,\n config: BetterstartConfig,\n options: GeneratorOptions = {}\n): PipelineResult {\n const paths = resolvePaths(config)\n const files: string[] = []\n const errors: string[] = []\n\n const steps: { name: string; run: () => string[] }[] = [\n {\n name: 'Database schema',\n run: () => generateDatabase(schema, cwd, paths.dbSchemaDir, options).files\n },\n {\n name: 'Server actions',\n run: () =>\n generateSingleActions(schema, cwd, paths.actionsDir, { force: options.force }).files\n },\n {\n name: 'React Query hook',\n run: () => generateSingleHook(schema, cwd, paths.hooksDir, options).files\n },\n {\n name: 'Form',\n run: () => generateSingleForm(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Single page',\n run: () => generateSinglePage(schema, cwd, paths.pagesDir, options).files\n },\n {\n name: 'Navigation',\n run: () => updateNavigation(schema, cwd, paths.cmsDir, options).files\n },\n {\n name: 'Cache module',\n run: () => generateCache(schema, cwd, paths.cmsDir, options).files\n }\n ]\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]\n const stepNum = i + 1\n try {\n const result = step.run()\n files.push(...result)\n if (!options.silent) console.log(` ${stepNum}. ${step.name} ✓`)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n errors.push(`${step.name}: ${msg}`)\n if (!options.silent) console.error(` ${stepNum}. ${step.name} ✗ — ${msg}`)\n }\n }\n\n return {\n success: errors.length === 0,\n files,\n errors\n }\n}\n\n// Re-export individual generators for direct use\nexport { generateActions, generateSingleActions } from './actions/index.js'\nexport { generateCache } from './cache.js'\nexport { generateColumns } from './columns/index.js'\nexport { generateCreatePage } from './create-page.js'\nexport { generateDatabase } from './database.js'\nexport { generateEditPage } from './edit-page.js'\nexport { generateForm, generateSingleForm } from './form/index.js'\nexport { generateHook, generateSingleHook } from './hook.js'\nexport { updateNavigation } from './navigation.js'\nexport { generatePage } from './page.js'\nexport { generatePageContent } from './page-content.js'\nexport { generateSinglePage } from './single-page.js'\nexport { generateTable } from './table.js'\n","/**\n * Post-generation tasks: auto db:push + lint:fix\n */\n\nimport { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport type { PackageManager } from '../utils/package-manager.js'\nimport { detectPackageManager } from '../utils/package-manager.js'\n\n/**\n * Load .env.local and set variables on process.env (if not already set)\n */\nfunction loadEnvFile(cwd: string): void {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return\n\n const content = fs.readFileSync(envPath, 'utf-8')\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n\n const eqIdx = trimmed.indexOf('=')\n if (eqIdx === -1) continue\n\n const key = trimmed.slice(0, eqIdx).trim()\n let value = trimmed.slice(eqIdx + 1).trim()\n\n // Strip surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1)\n }\n\n // Strip inline comments\n const commentIdx = value.indexOf(' #')\n if (commentIdx !== -1) {\n value = value.slice(0, commentIdx).trim()\n }\n\n if (!process.env[key]) {\n process.env[key] = value\n }\n }\n}\n\nfunction runPmScript(pm: PackageManager, script: string, cwd: string): boolean {\n const args = pm === 'bun' ? ['run', script] : [script]\n try {\n execFileSync(pm, args, { cwd, stdio: 'pipe' })\n return true\n } catch {\n return false\n }\n}\n\nfunction hasPkgScript(cwd: string, script: string): boolean {\n const pkgPath = path.join(cwd, 'package.json')\n if (!fs.existsSync(pkgPath)) return false\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>\n const scripts = pkg.scripts as Record<string, unknown> | undefined\n return !!scripts?.[script]\n } catch {\n return false\n }\n}\n\nexport interface PostGenerateOptions {\n skipMigration?: boolean\n}\n\nexport interface PostGenerateResult {\n dbPush: 'success' | 'skipped' | 'no-db-url' | 'failed'\n lintFix: 'success' | 'skipped' | 'failed'\n}\n\n/**\n * Run post-generation tasks: db:push and lint:fix\n */\nexport function runPostGenerate(\n cwd: string,\n schemaName: string,\n options: PostGenerateOptions = {}\n): PostGenerateResult {\n const pm = detectPackageManager(cwd)\n const result: PostGenerateResult = {\n dbPush: 'skipped',\n lintFix: 'skipped'\n }\n\n // 1. Database push\n if (!options.skipMigration) {\n loadEnvFile(cwd)\n\n const dbUrl = process.env.BETTERSTART_DATABASE_URL || process.env.DATABASE_URL\n\n if (!dbUrl) {\n result.dbPush = 'no-db-url'\n console.log('\\n Database: skipped (no DATABASE_URL configured)')\n console.log(' To sync later: run db:push after setting BETTERSTART_DATABASE_URL')\n } else if (hasPkgScript(cwd, 'db:push')) {\n console.log('\\n Running db:push...')\n const ok = runPmScript(pm, 'db:push', cwd)\n result.dbPush = ok ? 'success' : 'failed'\n console.log(ok ? ' Database schema synced' : ' Database push failed (run db:push manually)')\n } else {\n // Try running drizzle-kit push directly using project-local binary\n console.log('\\n Running drizzle-kit push...')\n const drizzleBin = path.join(cwd, 'node_modules', '.bin', 'drizzle-kit')\n try {\n execFileSync(drizzleBin, ['push', '--force'], { cwd, stdio: 'inherit' })\n result.dbPush = 'success'\n console.log(' Database schema synced')\n } catch {\n result.dbPush = 'failed'\n console.log(' Database push failed (run drizzle-kit push manually)')\n }\n }\n } else {\n console.log('\\n Database: skipped (--skip-migration)')\n }\n\n // 2. Lint fix\n if (hasPkgScript(cwd, 'lint:fix')) {\n console.log(' Running lint:fix...')\n const ok = runPmScript(pm, 'lint:fix', cwd)\n result.lintFix = ok ? 'success' : 'failed'\n console.log(ok ? ' Code formatted' : ' Lint fix had issues (run lint:fix manually)')\n } else {\n // Try biome directly using project-local binary\n const biomeBin = path.join(cwd, 'node_modules', '.bin', 'biome')\n try {\n execFileSync(biomeBin, ['check', '--write', '.'], { cwd, stdio: 'pipe' })\n result.lintFix = 'success'\n console.log(' Code formatted with Biome')\n } catch {\n result.lintFix = 'skipped'\n }\n }\n\n // Next steps\n console.log('\\n Next steps:')\n console.log(' 1. Review the generated files')\n if (options.skipMigration || result.dbPush !== 'success') {\n console.log(' 2. Run database migration: db:push')\n console.log(` 3. Start the dev server and visit /cms/${schemaName}`)\n } else {\n console.log(` 2. Start the dev server and visit /cms/${schemaName}`)\n }\n\n return result\n}\n","import { execFileSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun'\n\nconst LOCKFILE_MAP: Record<string, PackageManager> = {\n 'pnpm-lock.yaml': 'pnpm',\n 'package-lock.json': 'npm',\n 'yarn.lock': 'yarn',\n 'bun.lockb': 'bun',\n 'bun.lock': 'bun'\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n // Walk up the directory tree to find lockfiles (handles monorepos)\n let dir = path.resolve(cwd)\n const root = path.parse(dir).root\n while (dir !== root) {\n for (const [lockfile, pm] of Object.entries(LOCKFILE_MAP)) {\n if (fs.existsSync(path.join(dir, lockfile))) {\n return pm\n }\n }\n // Check packageManager field in package.json at this level\n const pkgPath = path.join(dir, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>\n if (typeof pkg.packageManager === 'string') {\n const name = pkg.packageManager.split('@')[0]\n if (name === 'pnpm' || name === 'npm' || name === 'yarn' || name === 'bun') {\n return name\n }\n }\n } catch {\n // ignore parse errors\n }\n }\n dir = path.dirname(dir)\n }\n\n return 'npm'\n}\n\nexport function installCommand(pm: PackageManager): string {\n return pm === 'yarn' ? 'yarn' : `${pm} install`\n}\n\nexport function addCommand(pm: PackageManager, deps: string[], dev = false): string {\n const devFlag = dev ? (pm === 'yarn' ? '--dev' : '-D') : ''\n\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${devFlag} ${deps.join(' ')}`.trim()\n case 'yarn':\n return `yarn add ${devFlag} ${deps.join(' ')}`.trim()\n case 'bun':\n return `bun add ${devFlag} ${deps.join(' ')}`.trim()\n default:\n return `npm install ${devFlag} ${deps.join(' ')}`.trim()\n }\n}\n\nexport function runCommand(pm: PackageManager, script: string): string {\n switch (pm) {\n case 'pnpm':\n return `pnpm ${script}`\n case 'yarn':\n return `yarn ${script}`\n case 'bun':\n return `bun run ${script}`\n default:\n return `npm run ${script}`\n }\n}\n\nexport function execPm(pm: PackageManager, args: string[], cwd: string): void {\n execFileSync(pm, args, { cwd, stdio: 'inherit' })\n}\n\n/**\n * Returns the binary + leading args to run `create-next-app` via the given package manager.\n * Using the native PM avoids nested-npx issues (e.g. running inside `npx @betterstart/cli`).\n */\nexport function createNextAppCommand(pm: PackageManager): { bin: string; prefix: string[] } {\n switch (pm) {\n case 'pnpm':\n return { bin: 'pnpm', prefix: ['create', 'next-app@latest'] }\n case 'yarn':\n return { bin: 'yarn', prefix: ['create', 'next-app@latest'] }\n case 'bun':\n return { bin: 'bunx', prefix: ['create-next-app@latest'] }\n default:\n return { bin: 'npx', prefix: ['create-next-app@latest'] }\n }\n}\n","import { execFileSync, spawn } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\nimport { getDefaultConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport { promptDatabase } from '../init/prompts/database.js'\nimport { promptFeatures } from '../init/prompts/features.js'\nimport { promptProject } from '../init/prompts/project.js'\nimport { scaffoldApiRoutes } from '../init/scaffolders/api-routes.js'\nimport { scaffoldAuth } from '../init/scaffolders/auth.js'\nimport { regenerateCmsDoc, scaffoldBase } from '../init/scaffolders/base.js'\nimport { scaffoldBiome } from '../init/scaffolders/biome.js'\nimport { scaffoldComponents } from '../init/scaffolders/components.js'\nimport { scaffoldDatabase } from '../init/scaffolders/database.js'\nimport { installDependenciesAsync } from '../init/scaffolders/dependencies.js'\nimport { detectDevPort, scaffoldEnv } from '../init/scaffolders/env.js'\nimport { scaffoldLayout } from '../init/scaffolders/layout.js'\nimport { scaffoldPreset } from '../init/scaffolders/preset.js'\nimport { scaffoldTailwind } from '../init/scaffolders/tailwind.js'\nimport { scaffoldTsconfig } from '../init/scaffolders/tsconfig.js'\nimport { detectProject } from '../utils/detect.js'\nimport { createNextAppCommand, detectPackageManager, runCommand } from '../utils/package-manager.js'\nimport { buildSeedScript } from './seed.js'\n\nexport const initCommand = new Command('init')\n .description('Scaffold CMS into a new or existing Next.js project')\n .argument('[name]', 'Project name (creates new directory if fresh project)')\n .option('--preset <preset>', 'Starter preset: blank, blog, or full', 'blog')\n .option('-y, --yes', 'Skip all prompts (accept defaults)')\n .option(\n '--database-url <url>',\n 'PostgreSQL database connection string (postgres:// or postgresql://)'\n )\n .option('--force', 'Overwrite all existing CMS files (nuclear option)')\n .action(\n async (\n name: string | undefined,\n options: { preset: string; yes?: boolean; databaseUrl?: string; force?: boolean }\n ) => {\n p.intro(pc.bgCyan(pc.black(' BetterStart CMS ')))\n\n let cwd = process.cwd()\n let project = detectProject(cwd)\n let pm = detectPackageManager(cwd)\n let isFreshProject = false\n\n // Determine srcDir\n let srcDir: boolean\n if (project.isExisting) {\n p.log.info(`Next.js project detected ${pc.dim('·')} ${pc.cyan(pm)}`)\n srcDir = project.hasSrcDir\n\n if (!project.hasTypeScript) {\n p.log.error('TypeScript is required. Please add a tsconfig.json first.')\n process.exit(1)\n }\n\n if (options.force) {\n // Nuclear option: wipe all CMS-owned directories and root-level files\n const nukeDirs = ['cms', 'app/(cms)', 'src/app/(cms)']\n const nukeFiles = ['cms.config.ts', 'CMS.md', 'drizzle.config.ts']\n let nuked = 0\n for (const dir of nukeDirs) {\n const fullPath = path.resolve(cwd, dir)\n if (fs.existsSync(fullPath)) {\n fs.rmSync(fullPath, { recursive: true, force: true })\n nuked++\n }\n }\n for (const file of nukeFiles) {\n const fullPath = path.resolve(cwd, file)\n if (fs.existsSync(fullPath)) {\n fs.unlinkSync(fullPath)\n nuked++\n }\n }\n if (nuked > 0) {\n p.log.warn(`${pc.yellow('Force mode:')} removed ${nuked} existing CMS paths`)\n }\n // Re-detect project after wipe\n project = detectProject(cwd)\n } else if (project.conflicts.length > 0) {\n const conflictLines = project.conflicts.map((c) => `${pc.yellow('▲')} ${c}`)\n conflictLines.push(\n '',\n pc.dim('Existing files will not be overwritten.'),\n pc.dim(`Use ${pc.bold('--force')} to remove existing CMS files before scaffolding.`)\n )\n p.note(conflictLines.join('\\n'), pc.yellow('Conflicts'))\n if (!options.yes) {\n const proceed = await p.confirm({\n message: 'Continue anyway?',\n initialValue: true\n })\n if (p.isCancel(proceed) || !proceed) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n }\n }\n } else {\n p.log.info('No Next.js project found — fresh project mode')\n const projectPrompt = await promptProject(name)\n srcDir = projectPrompt.useSrcDir\n\n // Ask for preferred package manager\n if (!options.yes) {\n const pmChoice = await p.select({\n message: 'Which package manager do you want to use?',\n options: [\n { value: 'pnpm' as const, label: 'pnpm', hint: 'recommended' },\n { value: 'npm' as const, label: 'npm' },\n { value: 'yarn' as const, label: 'yarn' },\n { value: 'bun' as const, label: 'bun' }\n ]\n })\n if (p.isCancel(pmChoice)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n pm = pmChoice\n }\n\n // Run create-next-app using the selected package manager's native command\n // to avoid nested-npx issues (e.g. when running via `npx @betterstart/cli`)\n const displayName =\n projectPrompt.projectName === '.' ? path.basename(cwd) : projectPrompt.projectName\n\n const { bin, prefix } = createNextAppCommand(pm)\n const cnaArgs = [\n ...prefix,\n projectPrompt.projectName,\n '--yes',\n '--typescript',\n '--tailwind',\n '--app',\n '--turbopack',\n '--biome',\n '--react-compiler',\n `--use-${pm}`\n ]\n if (srcDir) cnaArgs.push('--src-dir')\n else cnaArgs.push('--no-src-dir')\n\n p.log.step(`Creating Next.js app: ${pc.cyan(displayName)}`)\n\n try {\n execFileSync(bin, cnaArgs, {\n cwd,\n stdio: 'inherit',\n timeout: 120_000\n })\n } catch (err) {\n p.log.error(err instanceof Error ? err.message : 'create-next-app failed')\n p.log.info(\n `You can create the project manually:\\n ${pc.cyan(`npx create-next-app@latest ${projectPrompt.projectName} --typescript --tailwind --app`)}\\n Then run ${pc.cyan('betterstart init')} inside it.`\n )\n process.exit(1)\n }\n\n // Move into the new project directory\n cwd = path.resolve(cwd, projectPrompt.projectName)\n\n // Verify the project was actually created\n const hasPackageJson = fs.existsSync(path.join(cwd, 'package.json'))\n const hasNextConfig = ['next.config.ts', 'next.config.js', 'next.config.mjs'].some((f) =>\n fs.existsSync(path.join(cwd, f))\n )\n\n if (!hasPackageJson || !hasNextConfig) {\n p.log.error(\n 'create-next-app completed but the project was not created. This can happen with nested npx calls.'\n )\n const manualCmd = `npx create-next-app@latest ${projectPrompt.projectName} --typescript --tailwind --app`\n p.log.info(\n `Create the project manually:\\n ${pc.cyan(manualCmd)}\\n Then run ${pc.cyan('betterstart init')} inside it.`\n )\n process.exit(1)\n }\n\n p.log.success(`Created ${displayName} Next.js project`)\n project = detectProject(cwd)\n isFreshProject = true\n }\n\n // Feature prompts\n const features = options.yes\n ? { includeEmail: true, preset: options.preset as 'blank' | 'blog' | 'full' }\n : await promptFeatures(options.preset)\n\n // Database URL — check existing .env.local first, then prompt if needed\n let databaseUrl: string | undefined\n const existingDbUrl = readExistingDbUrl(cwd)\n\n if (options.yes) {\n // Non-interactive mode: --database-url flag > existing env > placeholder\n if (options.databaseUrl) {\n if (!isValidDbUrl(options.databaseUrl)) {\n p.log.error(\n `Invalid database URL. Must start with ${pc.cyan('postgres://')} or ${pc.cyan('postgresql://')}`\n )\n process.exit(1)\n }\n databaseUrl = options.databaseUrl\n } else if (existingDbUrl) {\n databaseUrl = existingDbUrl\n }\n // else: no flag, no existing → use placeholder (databaseUrl stays undefined)\n } else if (existingDbUrl) {\n // Interactive mode but a valid URL already exists — skip the prompt\n const masked = maskDbUrl(existingDbUrl)\n p.log.info(`Using existing database URL from .env.local ${pc.dim(`(${masked})`)}`)\n databaseUrl = existingDbUrl\n } else {\n const dbResult = await promptDatabase()\n databaseUrl = dbResult.url\n }\n\n // Build config\n const config: BetterstartConfig = {\n ...getDefaultConfig(srcDir),\n features: { email: features.includeEmail }\n }\n\n // Run scaffolders — group fast steps under one spinner, then show results in a note box\n interface ScaffoldResult {\n label: string\n result: string\n }\n const results: ScaffoldResult[] = []\n const s = p.spinner()\n\n s.start('Directory structure')\n\n const baseFiles = scaffoldBase({ cwd, config })\n results.push({ label: 'Directory structure', result: `${baseFiles.length} files` })\n\n s.message('TypeScript aliases')\n const tsResult = scaffoldTsconfig(cwd)\n results.push({\n label: 'TypeScript aliases',\n result: tsResult.added.length > 0 ? `${tsResult.added.length} paths` : 'already set'\n })\n\n s.message('Tailwind CSS')\n const twResult = scaffoldTailwind(cwd, srcDir)\n results.push({\n label: 'Tailwind CSS',\n result: twResult.appended ? 'updated' : twResult.file ? 'already set' : 'no CSS file'\n })\n\n s.message('Environment variables')\n const envResult = scaffoldEnv(cwd, { includeEmail: features.includeEmail, databaseUrl })\n const envCount = envResult.added.length + envResult.updated.length\n results.push({\n label: 'Environment variables',\n result: envCount > 0 ? `${envCount} vars` : 'already set'\n })\n\n s.message('Database')\n const dbFiles = scaffoldDatabase({ cwd, config })\n results.push({ label: 'Database', result: `${dbFiles.length} files` })\n\n s.message('Authentication')\n const authFiles = scaffoldAuth({ cwd, config })\n results.push({ label: 'Authentication', result: `${authFiles.length} files` })\n\n s.message('Components')\n const compFiles = scaffoldComponents({ cwd, config })\n results.push({ label: 'Components', result: `${compFiles.length} files` })\n\n s.message('Pages & layouts')\n const layoutFiles = scaffoldLayout({ cwd, config })\n results.push({ label: 'Pages & layouts', result: `${layoutFiles.length} files` })\n\n s.message('API routes')\n const apiFiles = scaffoldApiRoutes({ cwd, config })\n results.push({ label: 'API routes', result: `${apiFiles.length} routes` })\n\n s.message('Linter')\n let linterResult: string\n if (project.linter.type === 'none') {\n const biomeResult = scaffoldBiome(cwd, project.linter)\n linterResult = biomeResult.installed ? 'biome (new)' : 'none'\n } else {\n linterResult = project.linter.type\n }\n results.push({ label: 'Linter', result: linterResult })\n\n // Build the note content before stopping the spinner\n const maxLabel = Math.max(...results.map((r) => r.label.length))\n const noteLines = results.map((r) => {\n const padded = r.label.padEnd(maxLabel + 3)\n return `${pc.green('✓')} ${padded}${pc.dim(r.result)}`\n })\n\n // Stop spinner quietly and erase the empty stop line, then show results card\n s.stop('')\n process.stdout.write('\\x1B[2A\\x1B[J')\n p.note(noteLines.join('\\n'), 'Scaffolded CMS')\n\n // If drizzle.config.ts already existed (wasn't created), offer to update it\n const drizzleConfigPath = path.join(cwd, 'drizzle.config.ts')\n if (!dbFiles.includes('drizzle.config.ts') && fs.existsSync(drizzleConfigPath)) {\n if (options.force) {\n const { readTemplate } = await import('../init/templates/reader.js')\n fs.writeFileSync(drizzleConfigPath, readTemplate('drizzle.config.ts'), 'utf-8')\n p.log.success('Updated drizzle.config.ts')\n } else if (!options.yes) {\n const overwrite = await p.confirm({\n message: 'drizzle.config.ts already exists. Overwrite with latest version?',\n initialValue: true\n })\n if (!p.isCancel(overwrite) && overwrite) {\n const { readTemplate } = await import('../init/templates/reader.js')\n fs.writeFileSync(drizzleConfigPath, readTemplate('drizzle.config.ts'), 'utf-8')\n p.log.success('Updated drizzle.config.ts')\n }\n }\n }\n\n // Install dependencies (async so spinner can animate)\n s.start('Installing dependencies (this may take a minute)')\n const depsResult = await installDependenciesAsync({\n cwd,\n pm,\n includeEmail: features.includeEmail,\n includeBiome: project.linter.type === 'none'\n })\n let depsInstalled = false\n if (depsResult.success) {\n s.stop('')\n depsInstalled = true\n } else {\n s.stop('Failed to install dependencies')\n p.log.warning(depsResult.error ?? 'Unknown error')\n p.log.info(\n `You can install them manually:\\n ${pc.cyan(`${pm} add ${depsResult.coreDeps.join(' ')}`)}\\n ${pc.cyan(`${pm} add -D ${depsResult.devDeps.join(' ')}`)}`\n )\n }\n\n // Apply preset schemas + run entity generation + regenerate CMS.md\n if (depsInstalled) {\n process.stdout.write('\\x1B[2A\\x1B[J')\n }\n s.start(`Applying ${features.preset} preset`)\n const presetResult = scaffoldPreset({ cwd, config, preset: features.preset })\n // Regenerate CMS.md with full documentation\n {\n const entityNames: string[] = []\n const formNames: string[] = []\n const schemasDir = path.join(cwd, config.paths.schemas)\n const formsDir = path.join(schemasDir, 'forms')\n if (fs.existsSync(schemasDir)) {\n for (const f of fs.readdirSync(schemasDir)) {\n if (f.endsWith('.json')) entityNames.push(f.replace('.json', ''))\n }\n }\n if (fs.existsSync(formsDir)) {\n for (const f of fs.readdirSync(formsDir)) {\n if (f.endsWith('.json')) formNames.push(f.replace('.json', ''))\n }\n }\n regenerateCmsDoc(cwd, config, {\n preset: features.preset,\n schemas: entityNames,\n forms: formNames\n })\n }\n s.stop('')\n process.stdout.write('\\x1B[2A\\x1B[J')\n\n // Build combined note for deps + preset\n const installLines: string[] = []\n if (depsInstalled) {\n installLines.push(\n `${pc.green('✓')} Dependencies ${pc.dim(`${depsResult.coreDeps.length} deps + ${depsResult.devDeps.length} dev deps`)}`\n )\n }\n if (presetResult.errors.length > 0) {\n installLines.push(\n `${pc.yellow('▲')} Preset ${pc.dim(`${features.preset} — ${presetResult.errors.length} warning(s)`)}`\n )\n for (const err of presetResult.errors) {\n installLines.push(` ${pc.dim(err)}`)\n }\n } else {\n installLines.push(\n `${pc.green('✓')} Preset ${pc.dim(`${features.preset} — ${presetResult.schemas.length} schemas, ${presetResult.generatedFiles.length} files`)}`\n )\n }\n p.note(installLines.join('\\n'), 'Installed')\n\n // Push database schema if env var is configured (after preset so entity tables are included)\n let dbPushed = false\n if (depsResult.success && hasDbUrl(cwd)) {\n s.start('Pushing database schema (drizzle-kit push)')\n const pushResult = await runDrizzlePush(cwd)\n if (pushResult.success) {\n s.stop(`${pc.green('✓')} Database schema pushed`)\n dbPushed = true\n } else {\n s.stop('Database push failed')\n p.log.warning(pushResult.error ?? 'Unknown error')\n p.log.info(`You can run it manually: ${pc.cyan('npx drizzle-kit push')}`)\n }\n }\n\n // Auto-seed admin user (only when db push succeeded and interactive mode)\n let seedEmail: string | undefined\n let seedPassword: string | undefined\n let seedSuccess = false\n\n if (dbPushed && !options.yes) {\n p.note(pc.dim('Create your first admin user to access the CMS.'), 'Admin account')\n\n const credentials = await p.group(\n {\n email: () =>\n p.text({\n message: 'Admin email',\n placeholder: 'admin@example.com',\n validate: (v) => {\n if (!v || !v.includes('@')) return 'Please enter a valid email'\n }\n }),\n password: () =>\n p.password({\n message: 'Admin password',\n validate: (v) => {\n if (!v || v.length < 8) return 'Password must be at least 8 characters'\n }\n })\n },\n {\n onCancel: () => {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n }\n )\n\n seedEmail = credentials.email\n seedPassword = credentials.password\n\n s.start('Creating admin user')\n let seedResult = await runSeed(\n cwd,\n config.paths?.cms ?? './cms',\n credentials.email,\n credentials.password\n )\n\n if (seedResult.existingUser) {\n s.stop(`${pc.yellow('▲')} Admin user already exists (${seedResult.existingUser})`)\n const replace = await p.confirm({\n message: 'Replace existing admin user?',\n initialValue: false\n })\n if (!p.isCancel(replace) && replace) {\n s.start('Replacing admin user')\n seedResult = await runSeed(\n cwd,\n config.paths?.cms ?? './cms',\n credentials.email,\n credentials.password,\n true\n )\n } else {\n seedSuccess = true\n }\n }\n\n if (seedResult.success) {\n s.stop(`${pc.green('✓')} Admin user created`)\n seedSuccess = true\n } else if (!seedSuccess && seedResult.error) {\n s.stop(`${pc.red('✗')} Failed to create admin user`)\n p.note(\n `${pc.red(seedResult.error)}\\n\\nRun manually: ${pc.cyan('npx betterstart seed')}`,\n pc.red('Seed failed')\n )\n }\n }\n\n // Git init + commit for fresh projects\n if (isFreshProject) {\n s.start('Creating initial git commit')\n try {\n execFileSync('git', ['init'], { cwd, stdio: 'pipe' })\n execFileSync('git', ['add', '.'], { cwd, stdio: 'pipe' })\n execFileSync('git', ['commit', '-m', 'Initial commit from BetterStart'], {\n cwd,\n stdio: 'pipe'\n })\n s.stop('Created initial git commit')\n } catch {\n s.stop('Git commit skipped')\n }\n }\n\n const totalFiles =\n baseFiles.length +\n dbFiles.length +\n authFiles.length +\n compFiles.length +\n layoutFiles.length +\n apiFiles.length\n\n // Summary\n const summaryLines: string[] = [\n `Preset: ${pc.cyan(features.preset)}`,\n `Files created: ${pc.cyan(String(totalFiles))}`,\n `Env vars: ${envResult.added.length} added, ${envResult.skipped.length} skipped`\n ]\n\n if (seedSuccess && seedEmail && seedPassword) {\n summaryLines.push(\n '',\n `Admin: ${pc.cyan(seedEmail)}`,\n `Password: ${pc.cyan(seedPassword)}`,\n `CMS: ${pc.cyan(`http://localhost:${detectDevPort(cwd)}/cms/login`)}`\n )\n }\n\n // Next steps\n const nextSteps: string[] = []\n let step = 1\n const envStepLabel = databaseUrl\n ? `Fill in remaining values in ${pc.cyan('.env.local')}`\n : `Fill in values in ${pc.cyan('.env.local')}`\n nextSteps.push(` ${step++}. ${envStepLabel}`)\n if (!dbPushed) {\n nextSteps.push(` ${step++}. Run ${pc.cyan('npx drizzle-kit push')} to sync the database`)\n }\n if (!seedSuccess) {\n nextSteps.push(\n ` ${step++}. Run ${pc.cyan('npx betterstart seed')} to create an admin user`\n )\n }\n nextSteps.push(` ${step++}. Run ${pc.cyan('pnpm run dev')} to start the development server`)\n nextSteps.push(\n ` ${step++}. Run ${pc.cyan('npx betterstart generate <schema>')} to create content types`\n )\n\n summaryLines.push('', 'Next steps:', ...nextSteps)\n\n p.note(summaryLines.join('\\n'), 'CMS scaffolded successfully')\n\n // Offer to start the dev server (interactive mode only)\n if (!options.yes) {\n const devCmd = runCommand(pm, 'dev')\n const startDev = await p.confirm({\n message: 'Start the development server?',\n initialValue: true\n })\n\n if (!p.isCancel(startDev) && startDev) {\n p.outro(`Starting ${pc.cyan(devCmd)}...`)\n const [bin, ...args] = devCmd.split(' ')\n spawn(bin, args, { cwd, stdio: 'inherit' })\n return\n }\n }\n\n p.outro('Done!')\n }\n )\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Validate a database connection URL */\nfunction isValidDbUrl(url: string): boolean {\n return url.startsWith('postgres://') || url.startsWith('postgresql://')\n}\n\n/** Read BETTERSTART_DATABASE_URL from .env.local, returning the value if it's a real URL. */\nfunction readExistingDbUrl(cwd: string): string | undefined {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return undefined\n const content = fs.readFileSync(envPath, 'utf-8')\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.startsWith('#') || !trimmed.includes('=')) continue\n const [key, ...rest] = trimmed.split('=')\n if (key?.trim() === 'BETTERSTART_DATABASE_URL') {\n const val = rest\n .join('=')\n .replace(/^['\"]|['\"]$/g, '')\n .trim()\n if (\n val.length > 0 &&\n !val.startsWith('your_') &&\n val !== 'postgresql://...' &&\n isValidDbUrl(val)\n ) {\n return val\n }\n }\n }\n return undefined\n}\n\n/** Mask a database URL for display: show host only. */\nfunction maskDbUrl(url: string): string {\n try {\n const parsed = new URL(url)\n return `${parsed.protocol}//${parsed.host}/***`\n } catch {\n return 'postgres://***'\n }\n}\n\n/** Check if BETTERSTART_DATABASE_URL is set in .env.local */\nfunction hasDbUrl(cwd: string): boolean {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return false\n const content = fs.readFileSync(envPath, 'utf-8')\n // Check the var exists and has a non-placeholder value\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.startsWith('#') || !trimmed.includes('=')) continue\n const [key, ...rest] = trimmed.split('=')\n if (key?.trim() === 'BETTERSTART_DATABASE_URL') {\n const val = rest.join('=').trim()\n const unquoted = val.replace(/^['\"]|['\"]$/g, '')\n return unquoted.length > 0 && !unquoted.startsWith('your_') && unquoted !== 'postgresql://...'\n }\n }\n return false\n}\n\ninterface SeedResult {\n success: boolean\n error: string | null\n existingUser?: string\n}\n\n/** Write seed script, run it with tsx, clean up. Returns success/error. */\nfunction runSeed(\n cwd: string,\n cmsDir: string,\n email: string,\n password: string,\n overwrite = false\n): Promise<SeedResult> {\n const scriptsDir = path.join(cwd, cmsDir, 'scripts')\n const seedPath = path.join(scriptsDir, 'seed.ts')\n\n if (!fs.existsSync(scriptsDir)) {\n fs.mkdirSync(scriptsDir, { recursive: true })\n }\n fs.writeFileSync(seedPath, buildSeedScript(), 'utf-8')\n\n const cleanup = () => {\n try {\n fs.unlinkSync(seedPath)\n if (fs.existsSync(scriptsDir) && fs.readdirSync(scriptsDir).length === 0) {\n fs.rmdirSync(scriptsDir)\n }\n } catch {\n // Not critical\n }\n }\n\n return new Promise((resolve) => {\n const tsxBin = path.join(cwd, 'node_modules', '.bin', 'tsx')\n const child = spawn(tsxBin, [seedPath], {\n cwd,\n stdio: 'pipe',\n env: {\n ...process.env,\n SEED_EMAIL: email,\n SEED_PASSWORD: password,\n SEED_NAME: 'Admin',\n ...(overwrite ? { SEED_OVERWRITE: 'true' } : {})\n }\n })\n let stdout = ''\n let stderr = ''\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString()\n })\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n const timeout = setTimeout(() => {\n child.kill()\n cleanup()\n resolve({ success: false, error: 'Seed timed out after 30 seconds' })\n }, 30_000)\n child.on('close', (code) => {\n clearTimeout(timeout)\n cleanup()\n if (code === 0) {\n resolve({ success: true, error: null })\n } else if (code === 2) {\n // Exit code 2 = user already exists\n const name = stdout.match(/EXISTING_USER:(.+)/)?.[1]?.trim()\n resolve({ success: false, error: null, existingUser: name ?? email })\n } else {\n resolve({ success: false, error: parseSeedError(stdout, stderr) })\n }\n })\n child.on('error', (err) => {\n clearTimeout(timeout)\n cleanup()\n resolve({ success: false, error: parseSeedError('', err.message) })\n })\n })\n}\n\n/** Extract a human-readable error from seed script output */\nfunction parseSeedError(stdout: string, stderr: string): string {\n // Check for common patterns in stderr/stdout\n const combined = `${stdout}\\n${stderr}`\n\n // \"Seed failed: <message>\" from the catch handler\n const seedFailed = combined.match(/Seed failed:\\s*(.+)/)?.[1]?.trim()\n if (seedFailed) return seedFailed\n\n // \"Failed to create user\" from auth API failure\n if (combined.includes('Failed to create user')) return 'Auth API failed to create user'\n\n // Connection errors\n if (combined.includes('ECONNREFUSED') || combined.includes('connection refused'))\n return 'Could not connect to database'\n if (combined.includes('BETTERSTART_DATABASE_URL')) return 'Database URL is missing or invalid'\n if (combined.includes('password authentication failed'))\n return 'Database authentication failed — check your connection string'\n if (combined.includes('does not exist') && combined.includes('relation'))\n return 'Database tables not found — run npx drizzle-kit push first'\n if (combined.includes('MODULE_NOT_FOUND') || combined.includes('Cannot find module'))\n return 'Missing dependencies — run your package manager install first'\n\n // Fall back to first meaningful line of stderr\n const firstLine = stderr\n .split('\\n')\n .map((l) => l.trim())\n .find((l) => l.length > 0 && !l.startsWith('at ') && !l.startsWith('node:'))\n if (firstLine) return firstLine\n\n return 'Unknown error — run npx betterstart seed for details'\n}\n\n/** Run drizzle-kit push to sync the database schema */\nfunction runDrizzlePush(cwd: string): Promise<{ success: boolean; error: string | null }> {\n return new Promise((resolve) => {\n const drizzleBin = path.join(cwd, 'node_modules', '.bin', 'drizzle-kit')\n const child = spawn(drizzleBin, ['push', '--force'], {\n cwd,\n stdio: 'pipe',\n env: { ...process.env }\n })\n let stderr = ''\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n child.on('close', (code) => {\n if (code === 0) resolve({ success: true, error: null })\n else resolve({ success: false, error: stderr || `drizzle-kit push exited with code ${code}` })\n })\n child.on('error', (err) => {\n resolve({ success: false, error: err.message })\n })\n })\n}\n","import { execFileSync } from 'node:child_process'\n\nimport * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nexport interface DatabasePromptResult {\n url: string\n}\n\nconst VERCEL_NEON_URL = 'https://vercel.com/dashboard/integrations/checkout/neon'\n\n/**\n * Prompt the user to configure their database connection.\n *\n * Three paths:\n * 1. Vercel (Neon) — opens the integration page, then asks for the URL\n * 2. Supabase — \"coming soon\", loops back\n * 3. Manual — asks for the URL directly\n */\nexport async function promptDatabase(): Promise<DatabasePromptResult> {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const choice = await p.select({\n message: 'How would you like to connect your database?',\n options: [\n {\n value: 'vercel-neon' as const,\n label: 'Vercel (Neon)',\n hint: 'opens browser to create a free Postgres database'\n },\n {\n value: 'supabase' as const,\n label: 'Supabase',\n hint: 'coming soon'\n },\n {\n value: 'manual' as const,\n label: 'Enter connection string manually'\n }\n ]\n })\n\n if (p.isCancel(choice)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n if (choice === 'supabase') {\n p.log.warning('Supabase support is coming soon. Please choose another option.')\n continue\n }\n\n if (choice === 'vercel-neon') {\n openBrowser(VERCEL_NEON_URL)\n p.log.info(\n `Opening Vercel… Create a Neon Postgres database, then copy the ${pc.cyan('DATABASE_URL')} from the dashboard.`\n )\n }\n\n // Shared URL text prompt for both vercel-neon and manual\n const url = await promptConnectionString()\n return { url }\n }\n}\n\n/** Text prompt for the connection string with quote-stripping validation. */\nasync function promptConnectionString(): Promise<string> {\n const input = await p.text({\n message: 'Paste your database connection string',\n placeholder: 'postgres://user:pass@host/db',\n validate(val) {\n if (!val.trim()) {\n return 'A connection string is required to continue'\n }\n const stripped = val.replace(/^['\"]|['\"]$/g, '')\n if (!stripped.startsWith('postgres://') && !stripped.startsWith('postgresql://')) {\n return 'Must start with postgres:// or postgresql://'\n }\n }\n })\n\n if (p.isCancel(input)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n return (input as string).replace(/^['\"]|['\"]$/g, '').trim()\n}\n\n/** Best-effort browser open. Fails silently in headless / CI environments. */\nfunction openBrowser(url: string): void {\n try {\n const platform = process.platform\n if (platform === 'darwin') {\n execFileSync('open', [url], { stdio: 'ignore' })\n } else if (platform === 'win32') {\n execFileSync('cmd', ['/c', 'start', url], { stdio: 'ignore' })\n } else {\n execFileSync('xdg-open', [url], { stdio: 'ignore' })\n }\n } catch {\n // Silently ignore — user can open the URL manually\n }\n}\n","import * as p from '@clack/prompts'\n\nexport type Preset = 'blank' | 'blog' | 'full'\n\nexport interface FeaturesPromptResult {\n includeEmail: true\n preset: Preset\n}\n\n/**\n * Prompt for preset selection.\n */\nexport async function promptFeatures(presetOverride?: string): Promise<FeaturesPromptResult> {\n let preset: Preset\n if (presetOverride && isValidPreset(presetOverride)) {\n preset = presetOverride\n } else {\n const selected = await p.select({\n message: 'Select a preset:',\n options: [\n { value: 'blog' as const, label: 'Blog', hint: 'Posts + Categories (recommended)' },\n { value: 'blank' as const, label: 'Blank', hint: 'CMS shell only, no content types' },\n { value: 'full' as const, label: 'Full', hint: 'Blog + Navigation + Contact form' }\n ],\n initialValue: 'blog' as const\n })\n\n if (p.isCancel(selected)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n preset = selected\n }\n\n return { includeEmail: true, preset }\n}\n\nfunction isValidPreset(value: string): value is Preset {\n return value === 'blank' || value === 'blog' || value === 'full'\n}\n","import * as p from '@clack/prompts'\n\nexport interface ProjectPromptResult {\n projectName: string\n useSrcDir: boolean\n}\n\n/**\n * Prompt for project name and src/ directory (fresh project only).\n */\nexport async function promptProject(defaultName?: string): Promise<ProjectPromptResult> {\n const projectName = await p.text({\n message: 'What is your project name?',\n placeholder: defaultName ?? 'my-app',\n defaultValue: defaultName ?? 'my-app',\n validate: (value) => {\n if (!value.trim()) return 'Project name is required'\n if (value.trim() === '.') return undefined\n if (!/^[a-z0-9_-]+$/i.test(value.trim())) {\n return 'Project name can only contain letters, numbers, hyphens, and underscores'\n }\n return undefined\n }\n })\n\n if (p.isCancel(projectName)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n const useSrcDir = await p.confirm({\n message: 'Use src/ directory?',\n initialValue: false\n })\n\n if (p.isCancel(useSrcDir)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n\n return { projectName: projectName.trim(), useSrcDir }\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface ApiRoutesScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create CMS API routes under /api/cms/.\n */\nexport function scaffoldApiRoutes({ cwd, config }: ApiRoutesScaffoldOptions): string[] {\n const created: string[] = []\n const apiDir = path.resolve(cwd, config.paths.api)\n\n function write(relPath: string, content: string): void {\n const fullPath = path.join(apiDir, relPath)\n ensureDir(path.dirname(fullPath))\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.api, relPath))\n }\n }\n\n // Better Auth catch-all: /api/cms/auth/[...all]/route.ts\n write(path.join('auth', '[...all]', 'route.ts'), readTemplate('api/auth-route.ts'))\n\n // Upload: /api/cms/upload/route.ts\n write(path.join('upload', 'route.ts'), readTemplate('api/upload-route.ts'))\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport fse from 'fs-extra'\n\n/**\n * Ensure a directory exists, creating it recursively if needed.\n */\nexport function ensureDir(dirPath: string): void {\n fse.ensureDirSync(dirPath)\n}\n\n/**\n * Write a file, creating parent directories as needed.\n * Will NOT overwrite an existing file unless `force` is true.\n * Returns true if the file was written, false if skipped.\n */\nexport function safeWriteFile(filePath: string, content: string, force = false): boolean {\n if (!force && fs.existsSync(filePath)) {\n return false\n }\n ensureDir(path.dirname(filePath))\n fs.writeFileSync(filePath, content, 'utf-8')\n return true\n}\n\n/**\n * Copy a single file, creating parent directories as needed.\n * Will NOT overwrite an existing file unless `force` is true.\n */\nexport function safeCopyFile(src: string, dest: string, force = false): boolean {\n if (!force && fs.existsSync(dest)) {\n return false\n }\n ensureDir(path.dirname(dest))\n fs.copyFileSync(src, dest)\n return true\n}\n\n/**\n * Recursively copy a directory of templates.\n * Skips existing files unless `force` is true.\n * Returns lists of written and skipped file paths.\n */\nexport function copyTemplateDir(\n srcDir: string,\n destDir: string,\n force = false\n): { written: string[]; skipped: string[] } {\n const written: string[] = []\n const skipped: string[] = []\n\n function walk(currentSrc: string, currentDest: string): void {\n const entries = fs.readdirSync(currentSrc, { withFileTypes: true })\n for (const entry of entries) {\n const srcPath = path.join(currentSrc, entry.name)\n const destPath = path.join(currentDest, entry.name)\n\n if (entry.isDirectory()) {\n walk(srcPath, destPath)\n } else {\n if (safeCopyFile(srcPath, destPath, force)) {\n written.push(destPath)\n } else {\n skipped.push(destPath)\n }\n }\n }\n }\n\n walk(srcDir, destDir)\n return { written, skipped }\n}\n\n/**\n * Append content to a file if the marker text is not already present.\n * Creates the file if it doesn't exist.\n * Returns true if content was appended.\n */\nexport function appendToFile(filePath: string, content: string, marker: string): boolean {\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, 'utf-8')\n if (existing.includes(marker)) {\n return false\n }\n fs.writeFileSync(filePath, `${existing.trimEnd()}\\n${content}\\n`, 'utf-8')\n } else {\n ensureDir(path.dirname(filePath))\n fs.writeFileSync(filePath, `${content}\\n`, 'utf-8')\n }\n return true\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface AuthScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create Better Auth config, client, and middleware in cms/lib/auth/.\n */\nexport function scaffoldAuth({ cwd, config }: AuthScaffoldOptions): string[] {\n const created: string[] = []\n const authDir = path.resolve(cwd, config.paths.cms, 'lib', 'auth')\n\n function write(filename: string, content: string): void {\n const fullPath = path.join(authDir, filename)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, 'lib', 'auth', filename))\n }\n }\n\n write('auth.ts', readTemplate('lib/auth/auth.ts'))\n write('auth-client.ts', readTemplate('lib/auth/auth-client.ts'))\n write('middleware.ts', readTemplate('lib/auth/middleware.ts'))\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\n\nexport interface BaseScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\nexport interface CmsDocOptions {\n preset?: string\n schemas?: string[]\n forms?: string[]\n}\n\n/**\n * Create the cms/ directory structure, cms.config.ts, and CMS.md.\n */\nexport function scaffoldBase({ cwd, config }: BaseScaffoldOptions): string[] {\n const created: string[] = []\n\n // Create cms/ subdirectories\n const cmsDirs = [\n config.paths.cms,\n config.paths.schemas,\n path.join(config.paths.cms, 'db'),\n path.join(config.paths.cms, 'db', 'migrations'),\n path.join(config.paths.cms, 'lib', 'auth'),\n path.join(config.paths.cms, 'lib', 'actions'),\n path.join(config.paths.cms, 'lib', 'cache'),\n path.join(config.paths.cms, 'lib', 'markdown'),\n path.join(config.paths.cms, 'lib', 'emails'),\n path.join(config.paths.cms, 'lib'),\n path.join(config.paths.cms, 'hooks'),\n path.join(config.paths.cms, 'components', 'ui'),\n path.join(config.paths.cms, 'components', 'form'),\n path.join(config.paths.cms, 'components', 'data-table'),\n path.join(config.paths.cms, 'components', 'layout'),\n path.join(config.paths.cms, 'components', 'shared'),\n path.join(config.paths.cms, 'types'),\n path.join(config.paths.cms, 'utils'),\n path.join(config.paths.cms, 'data')\n ]\n\n for (const dir of cmsDirs) {\n ensureDir(path.resolve(cwd, dir))\n }\n\n // Create app route directories\n const cmsDir = path.dirname(config.paths.pages)\n const appDirs = [\n config.paths.pages,\n config.paths.login,\n config.paths.api,\n path.join(cmsDir, '(account)', 'profile'),\n ]\n\n for (const dir of appDirs) {\n ensureDir(path.resolve(cwd, dir))\n }\n\n // Write cms.config.ts\n const configContent = generateConfigFile(config)\n if (safeWriteFile(path.resolve(cwd, 'cms.config.ts'), configContent)) {\n created.push('cms.config.ts')\n }\n\n // Write CMS.md (basic version — regenerated after preset with full info)\n const cmsDoc = generateCmsDoc(config, {})\n if (safeWriteFile(path.resolve(cwd, 'CMS.md'), cmsDoc)) {\n created.push('CMS.md')\n }\n\n return created\n}\n\n/**\n * Regenerate CMS.md with full documentation including preset and schema info.\n * Called after the preset step so generated schemas can be listed.\n */\nexport function regenerateCmsDoc(\n cwd: string,\n config: BetterstartConfig,\n options: CmsDocOptions\n): void {\n const content = generateCmsDoc(config, options)\n fs.writeFileSync(path.resolve(cwd, 'CMS.md'), content, 'utf-8')\n}\n\nfunction generateConfigFile(config: BetterstartConfig): string {\n return `import { defineConfig } from '@betterstart/cli'\n\nexport default defineConfig({\n srcDir: ${String(config.srcDir)},\n\n paths: {\n cms: '${config.paths.cms}',\n schemas: '${config.paths.schemas}',\n pages: '${config.paths.pages}',\n login: '${config.paths.login}',\n api: '${config.paths.api}',\n },\n\n database: {\n provider: '${config.database.provider}',\n migrationsDir: '${config.database.migrationsDir}',\n },\n\n features: {\n email: ${String(config.features.email)},\n },\n\n linter: '${config.linter}',\n\n generated: {\n entities: [],\n singles: [],\n forms: [],\n },\n})\n`\n}\n\nfunction generateCmsDoc(config: BetterstartConfig, options: CmsDocOptions): string {\n const sections: string[] = []\n\n // Header\n sections.push(`# CMS\n\n> Auto-generated by [BetterStart CLI](https://github.com/betterstart/cli).\n> Regenerated on each \\`betterstart init\\`.`)\n\n // Preset\n if (options.preset) {\n sections.push(`## Preset\n\nThis project was initialized with the **${options.preset}** preset.`)\n }\n\n // Directory structure\n sections.push(`## Directory Structure\n\n| Path | Description |\n|------|-------------|\n| \\`cms/\\` | All CMS source code (you own this) |\n| \\`cms/schemas/\\` | Entity JSON schemas |\n| \\`cms/schemas/forms/\\` | Form JSON schemas |\n| \\`cms/db/\\` | Database client, schema, drizzle config |\n| \\`cms/lib/actions/\\` | Server actions (CRUD) |\n| \\`cms/lib/auth/\\` | Better Auth configuration |\n| \\`cms/lib/cache/\\` | Cache tags, queries, revalidation |\n| \\`cms/lib/emails/\\` | React Email templates |\n| \\`cms/hooks/\\` | React Query hooks |\n| \\`cms/components/\\` | UI components (shadcn-style) |\n| \\`cms/utils/\\` | Utility functions |\n| \\`${config.paths.pages}/\\` | Admin pages (auth-gated) |\n| \\`${config.paths.login}/\\` | Login page |\n| \\`${config.paths.api}/\\` | CMS API routes |`)\n\n // Generated content\n if (\n (options.schemas && options.schemas.length > 0) ||\n (options.forms && options.forms.length > 0)\n ) {\n const lines: string[] = ['## Generated Content', '']\n if (options.schemas && options.schemas.length > 0) {\n lines.push('### Entities')\n for (const s of options.schemas) {\n lines.push(`- **${s}** — \\`cms/schemas/${s}.json\\` → admin at \\`/cms/${s}\\``)\n }\n }\n if (options.forms && options.forms.length > 0) {\n lines.push('')\n lines.push('### Forms')\n for (const f of options.forms) {\n lines.push(`- **${f}** — \\`cms/schemas/forms/${f}.json\\` → admin at \\`/cms/forms/${f}\\``)\n }\n }\n sections.push(lines.join('\\n'))\n }\n\n // Commands\n sections.push(`## Commands\n\n\\`\\`\\`bash\n# Generate entity CRUD from a schema\nnpx betterstart generate <schema-name>\n\n# Generate with force overwrite\nnpx betterstart generate <schema-name> --force\n\n# Remove all generated files for an entity/form\nnpx betterstart remove <schema-name>\n\n# Create initial admin user\nnpx betterstart seed\n\\`\\`\\``)\n\n // Schema format\n sections.push(`## Schema Format\n\n### Entity Schema (\\`cms/schemas/<name>.json\\`)\n\n\\`\\`\\`json\n{\n \"name\": \"posts\",\n \"label\": \"Posts\",\n \"icon\": \"FileText\",\n \"fields\": [\n { \"name\": \"title\", \"type\": \"string\", \"label\": \"Title\", \"required\": true },\n { \"name\": \"content\", \"type\": \"richtext\", \"label\": \"Content\" }\n ]\n}\n\\`\\`\\`\n\nField types: \\`string\\`, \\`text\\`, \\`richtext\\`, \\`number\\`, \\`boolean\\`, \\`date\\`, \\`image\\`, \\`select\\`, \\`relationship\\`.\n\n### Form Schema (\\`cms/schemas/forms/<name>.json\\`)\n\n\\`\\`\\`json\n{\n \"name\": \"contact\",\n \"label\": \"Contact Form\",\n \"submitButtonText\": \"Send Message\",\n \"fields\": [\n { \"name\": \"email\", \"type\": \"email\", \"label\": \"Email\", \"required\": true },\n { \"name\": \"message\", \"type\": \"textarea\", \"label\": \"Message\", \"required\": true }\n ]\n}\n\\`\\`\\`\n\nField types: \\`text\\`, \\`textarea\\`, \\`email\\`, \\`phone\\`, \\`number\\`, \\`url\\`, \\`date\\`, \\`select\\`, \\`radio\\`, \\`checkbox\\`, \\`multiselect\\`, \\`file\\`.`)\n\n // Path aliases\n sections.push(`## Path Aliases\n\n| Alias | Resolves to |\n|-------|-------------|\n| \\`@cms/*\\` | \\`${config.paths.cms}/*\\` |`)\n\n // Environment variables\n sections.push(`## Environment Variables\n\nRequired variables in \\`.env.local\\`:\n\n| Variable | Description |\n|----------|-------------|\n| \\`BETTERSTART_DATABASE_URL\\` | PostgreSQL connection string |\n| \\`BETTERSTART_AUTH_SECRET\\` | Auth secret (\\`openssl rand -base64 32\\`) |\n| \\`BETTERSTART_AUTH_URL\\` | App URL (e.g. \\`http://localhost:3000\\`) |\n| \\`BETTERSTART_R2_*\\` | Cloudflare R2 storage credentials |\n| \\`BETTERSTART_RESEND_API_KEY\\` | Resend API key (if email enabled) |\n| \\`NOTIFICATION_EMAIL\\` | Fallback notification email address |`)\n\n // Configuration\n sections.push(`## Configuration\n\nEdit \\`cms.config.ts\\` to customize paths, database provider, and features.`)\n\n return `${sections.join('\\n\\n')}\\n`\n}\n","/**\n * Biome scaffolder: creates biome.json if no existing linter is detected\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { LinterInfo } from '../../utils/detect.js'\n\nexport interface BiomeScaffoldResult {\n /** Whether Biome was set up */\n installed: boolean\n /** Reason it was skipped (if any) */\n skippedReason: string | null\n}\n\n/**\n * Create biome.json config if no linter exists.\n * Does NOT install the package — the dependency installer (task 5.05) handles that.\n */\nexport function scaffoldBiome(cwd: string, linter: LinterInfo): BiomeScaffoldResult {\n if (linter.type !== 'none') {\n return {\n installed: false,\n skippedReason: `${linter.type} already configured (${linter.configFile})`\n }\n }\n\n const configPath = path.join(cwd, 'biome.json')\n if (fs.existsSync(configPath)) {\n return { installed: false, skippedReason: 'biome.json already exists' }\n }\n\n const config = {\n $schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n vcs: {\n enabled: true,\n clientKind: 'git',\n useIgnoreFile: true\n },\n organizeImports: {\n enabled: true\n },\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 100\n },\n linter: {\n enabled: true,\n rules: {\n recommended: true,\n correctness: {\n noUnusedImports: 'warn',\n noUnusedVariables: 'warn'\n },\n style: {\n noNonNullAssertion: 'off'\n }\n }\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n semicolons: 'asNeeded'\n }\n },\n files: {\n ignore: [\n 'node_modules',\n '.next',\n 'dist',\n 'build',\n '*.config.js',\n '*.config.mjs',\n '*.config.cjs'\n ]\n }\n }\n\n fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, 'utf-8')\n return { installed: true, skippedReason: null }\n}\n","import path from 'node:path'\nimport fs from 'fs-extra'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { findCliRoot } from '../../utils/cli-root.js'\nimport { detectProjectName } from '../../utils/detect.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { cmsDataTemplate } from '../templates/data/cms.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface ComponentScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Copy all CMS components, hooks, types, utils, data, and lib code into the project.\n */\nexport function scaffoldComponents({ cwd, config }: ComponentScaffoldOptions): string[] {\n const cms = path.resolve(cwd, config.paths.cms)\n const created: string[] = []\n\n function write(relPath: string, content: string): void {\n const fullPath = path.join(cms, relPath)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, relPath))\n }\n }\n\n // --- CSS ---\n write('cms-globals.css', readTemplate('cms-globals.css'))\n\n // --- Components: layout ---\n write('components/layout/cms-providers.tsx', readTemplate('components/layout/cms-providers.tsx'))\n write('components/layout/cms-nav-link.tsx', readTemplate('components/layout/cms-nav-link.tsx'))\n write('components/layout/cms-sidebar.tsx', readTemplate('components/layout/cms-sidebar.tsx'))\n write('components/layout/cms-header.tsx', readTemplate('components/layout/cms-header.tsx'))\n write('components/layout/cms-search.tsx', readTemplate('components/layout/cms-search.tsx'))\n // --- Components: shared ---\n write('components/shared/page-header.tsx', readTemplate('components/shared/page-header.tsx'))\n write('components/shared/delete-dialog.tsx', readTemplate('components/shared/delete-dialog.tsx'))\n write('components/shared/status-badge.tsx', readTemplate('components/shared/status-badge.tsx'))\n\n // --- Components: data-table ---\n write('components/data-table/data-table.tsx', readTemplate('components/data-table/data-table.tsx'))\n write('components/data-table/data-table-pagination.tsx', readTemplate('components/data-table/data-table-pagination.tsx'))\n write('components/data-table/data-table-toolbar.tsx', readTemplate('components/data-table/data-table-toolbar.tsx'))\n\n // --- Components: ui (raw file copy) ---\n const uiCreated = copyUiTemplates(cwd, config)\n created.push(...uiCreated)\n\n // --- Components: ui/tiptap (recursive copy) ---\n const tiptapCreated = copyTiptapTemplates(cwd, config)\n created.push(...tiptapCreated)\n\n // --- Types ---\n write('types/index.ts', readTemplate('types/index.ts'))\n write('types/auth.ts', readTemplate('types/auth.ts'))\n write('types/table-meta.ts', readTemplate('types/table-meta.ts'))\n\n // --- Utils ---\n write('utils/cn.ts', readTemplate('utils/cn.ts'))\n write('utils/seo.ts', readTemplate('utils/seo.ts'))\n write('utils/validation.ts', readTemplate('utils/validation.ts'))\n write('utils/webhook.ts', readTemplate('utils/webhook.ts'))\n write('utils/mailchimp.ts', readTemplate('utils/mailchimp.ts'))\n\n // --- Hooks ---\n write('hooks/use-upload.ts', readTemplate('hooks/use-upload.ts'))\n write('hooks/use-editor-image-upload.ts', readTemplate('hooks/use-editor-image-upload.ts'))\n write('hooks/use-local-storage.ts', readTemplate('hooks/use-local-storage.ts'))\n write('hooks/use-cms-theme.tsx', readTemplate('hooks/use-cms-theme.tsx'))\n write('hooks/use-users.ts', readTemplate('hooks/use-users.ts'))\n write('hooks/use-mobile.ts', readTemplate('hooks/use-mobile.ts'))\n\n // --- Data ---\n const projectName = detectProjectName(cwd)\n write('data/cms.ts', cmsDataTemplate(projectName))\n write('data/navigation.ts', readTemplate('data/navigation.ts'))\n\n // --- Lib ---\n write('lib/r2.ts', readTemplate('lib/r2.ts'))\n write('lib/actions/form-settings.ts', readTemplate('lib/actions/form-settings.ts'))\n write('lib/actions/upload.ts', readTemplate('lib/actions/upload.ts'))\n write('lib/actions/users.ts', readTemplate('lib/actions/users.ts'))\n\n // --- Markdown ---\n write('lib/markdown/render.ts', readTemplate('lib/markdown/render.ts'))\n write('lib/markdown/format.ts', readTemplate('lib/markdown/format.ts'))\n write('lib/markdown/cached.ts', readTemplate('lib/markdown/cached.ts'))\n\n // --- Schema metaschema ---\n const schemaCreated = copySchemaMetaschema(cwd, config)\n created.push(...schemaCreated)\n\n return created\n}\n\n/**\n * Copy raw .tsx UI component files from the CLI's templates/ui/ directory.\n */\nfunction copyUiTemplates(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const destDir = path.resolve(cwd, config.paths.cms, 'components', 'ui')\n\n const cliRoot = findCliRoot()\n const srcDir = path.join(cliRoot, 'templates', 'ui')\n\n if (!fs.existsSync(srcDir)) {\n return created\n }\n\n const files = fs\n .readdirSync(srcDir)\n .filter((f: string) => f.endsWith('.tsx') || f.endsWith('.ts'))\n\n for (const file of files) {\n const destPath = path.join(destDir, file)\n if (!fs.existsSync(destPath)) {\n fs.copyFileSync(path.join(srcDir, file), destPath)\n created.push(path.join(config.paths.cms, 'components', 'ui', file))\n }\n }\n\n return created\n}\n\n/**\n * Recursively copy the TipTap editor directory from templates/tiptap/ → cms/components/ui/tiptap/.\n */\nfunction copyTiptapTemplates(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const cliRoot = findCliRoot()\n const srcDir = path.join(cliRoot, 'templates', 'tiptap')\n const destDir = path.resolve(cwd, config.paths.cms, 'components', 'ui', 'tiptap')\n\n if (!fs.existsSync(srcDir)) {\n return created\n }\n\n copyDirRecursive(srcDir, destDir, config.paths.cms, created)\n return created\n}\n\nfunction copyDirRecursive(src: string, dest: string, cmsPrefix: string, created: string[]): void {\n fs.ensureDirSync(dest)\n const entries = fs.readdirSync(src, { withFileTypes: true })\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name)\n const destPath = path.join(dest, entry.name)\n if (entry.isDirectory()) {\n copyDirRecursive(srcPath, destPath, cmsPrefix, created)\n } else if (!fs.existsSync(destPath)) {\n fs.copyFileSync(srcPath, destPath)\n const relFromCms = path.relative(path.resolve(dest, '..', '..', '..', '..'), destPath)\n created.push(relFromCms)\n }\n }\n}\n\n/**\n * Copy schema.json metaschema into cms/schemas/ so users get IDE validation.\n */\nfunction copySchemaMetaschema(cwd: string, config: BetterstartConfig): string[] {\n const created: string[] = []\n const cliRoot = findCliRoot()\n const srcPath = path.join(cliRoot, 'templates', 'schema.json')\n const destPath = path.resolve(cwd, config.paths.schemas, 'schema.json')\n\n if (fs.existsSync(srcPath) && !fs.existsSync(destPath)) {\n fs.ensureDirSync(path.dirname(destPath))\n fs.copyFileSync(srcPath, destPath)\n created.push(path.join(config.paths.schemas, 'schema.json'))\n }\n\n return created\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type LinterType = 'eslint' | 'biome' | 'none'\n\nexport interface LinterInfo {\n /** Detected linter type */\n type: LinterType\n /** Config file found (if any) */\n configFile: string | null\n}\n\nexport interface ProjectInfo {\n /** Whether this is an existing Next.js project */\n isExisting: boolean\n /** Whether the project uses a src/ directory */\n hasSrcDir: boolean\n /** Whether TypeScript is configured */\n hasTypeScript: boolean\n /** Whether Tailwind CSS is configured */\n hasTailwind: boolean\n /** Detected linter info */\n linter: LinterInfo\n /** Conflicts found that would block init */\n conflicts: string[]\n}\n\nconst NEXT_CONFIG_FILES = ['next.config.ts', 'next.config.js', 'next.config.mjs']\n\nexport function detectProjectName(cwd: string): string {\n const pkgPath = path.join(cwd, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n if (typeof pkg.name === 'string' && pkg.name.length > 0) {\n return formatProjectName(pkg.name)\n }\n } catch {\n /* ignore */\n }\n }\n return formatProjectName(path.basename(cwd))\n}\n\nfunction formatProjectName(name: string): string {\n const base = name.includes('/') ? name.split('/').pop()! : name\n return base\n .replace(/[-_]+/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n .trim()\n}\n\nexport function detectProject(cwd: string): ProjectInfo {\n const isExisting = NEXT_CONFIG_FILES.some((f) => fs.existsSync(path.join(cwd, f)))\n\n const hasSrcDir = fs.existsSync(path.join(cwd, 'src'))\n\n const hasTypeScript =\n fs.existsSync(path.join(cwd, 'tsconfig.json')) ||\n fs.existsSync(path.join(cwd, 'tsconfig.app.json'))\n\n const hasTailwind = detectTailwind(cwd)\n const linter = detectLinter(cwd)\n\n const conflicts: string[] = []\n if (isExisting) {\n if (fs.existsSync(path.join(cwd, 'cms'))) {\n conflicts.push('cms/ directory already exists')\n }\n if (fs.existsSync(path.join(cwd, 'cms.config.ts'))) {\n conflicts.push('cms.config.ts already exists')\n }\n\n const appBase = hasSrcDir ? 'src/app' : 'app'\n if (fs.existsSync(path.join(cwd, appBase, '(cms)'))) {\n conflicts.push(`${appBase}/(cms)/ route group already exists`)\n }\n\n if (hasTsconfigCmsAliases(cwd)) {\n conflicts.push('@cms/* path aliases already exist in tsconfig.json')\n }\n\n if (hasEnvBetterstartVars(cwd)) {\n conflicts.push('BETTERSTART_* variables already exist in .env.local')\n }\n }\n\n return { isExisting, hasSrcDir, hasTypeScript, hasTailwind, linter, conflicts }\n}\n\n// ============================================================================\n// Linter Detection\n// ============================================================================\n\nconst BIOME_CONFIG_FILES = ['biome.json', 'biome.jsonc']\n\nconst ESLINT_CONFIG_FILES = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n '.eslintrc.json',\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n '.eslintrc'\n]\n\nexport function detectLinter(cwd: string): LinterInfo {\n // Check for Biome first (preferred)\n for (const f of BIOME_CONFIG_FILES) {\n if (fs.existsSync(path.join(cwd, f))) {\n return { type: 'biome', configFile: f }\n }\n }\n\n // Check for ESLint config files\n for (const f of ESLINT_CONFIG_FILES) {\n if (fs.existsSync(path.join(cwd, f))) {\n return { type: 'eslint', configFile: f }\n }\n }\n\n // Check package.json for eslintConfig field\n const pkgPath = path.join(cwd, 'package.json')\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))\n if (pkg.eslintConfig) {\n return { type: 'eslint', configFile: 'package.json (eslintConfig)' }\n }\n } catch {\n // ignore parse errors\n }\n }\n\n return { type: 'none', configFile: null }\n}\n\n// ============================================================================\n// Tailwind Detection\n// ============================================================================\n\nfunction detectTailwind(cwd: string): boolean {\n // Tailwind v4: check for CSS files with @import \"tailwindcss\" or @theme\n const cssFiles = ['globals.css', 'app.css', 'index.css'].flatMap((f) => [\n path.join(cwd, 'src', 'app', f),\n path.join(cwd, 'app', f),\n path.join(cwd, 'src', f),\n path.join(cwd, f)\n ])\n\n for (const cssFile of cssFiles) {\n if (fs.existsSync(cssFile)) {\n const content = fs.readFileSync(cssFile, 'utf-8')\n if (\n content.includes('@import \"tailwindcss\"') ||\n content.includes(\"@import 'tailwindcss'\") ||\n content.includes('@theme')\n ) {\n return true\n }\n }\n }\n\n // Also check postcss.config for tailwindcss plugin (v3 style)\n const postcssFiles = ['postcss.config.js', 'postcss.config.mjs', 'postcss.config.cjs']\n for (const f of postcssFiles) {\n if (fs.existsSync(path.join(cwd, f))) {\n const content = fs.readFileSync(path.join(cwd, f), 'utf-8')\n if (content.includes('tailwindcss') || content.includes('@tailwindcss')) {\n return true\n }\n }\n }\n\n return false\n}\n\nfunction hasTsconfigCmsAliases(cwd: string): boolean {\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n if (!fs.existsSync(tsconfigPath)) return false\n\n try {\n const content = fs.readFileSync(tsconfigPath, 'utf-8')\n return content.includes('@cms/')\n } catch {\n return false\n }\n}\n\nfunction hasEnvBetterstartVars(cwd: string): boolean {\n const envPath = path.join(cwd, '.env.local')\n if (!fs.existsSync(envPath)) return false\n\n try {\n const content = fs.readFileSync(envPath, 'utf-8')\n return content.includes('BETTERSTART_')\n } catch {\n return false\n }\n}\n","/**\n * Template: cms/data/cms.ts\n * CMS metadata (project name, etc.)\n */\nexport function cmsDataTemplate(projectName: string): string {\n return `export const cms = {\n name: '${projectName}',\n}\n`\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface DatabaseScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create database client, schema, and drizzle config in cms/db/.\n */\nexport function scaffoldDatabase({ cwd, config }: DatabaseScaffoldOptions): string[] {\n const created: string[] = []\n const dbDir = path.resolve(cwd, config.paths.cms, 'db')\n\n function write(filename: string, content: string): void {\n const fullPath = path.join(dbDir, filename)\n if (safeWriteFile(fullPath, content)) {\n created.push(path.join(config.paths.cms, 'db', filename))\n }\n }\n\n write('client.ts', readTemplate('db/client.ts'))\n write('schema.ts', readTemplate('db/schema.ts'))\n\n // Drizzle config goes at project root (where drizzle-kit expects it)\n const drizzleConfigPath = path.resolve(cwd, 'drizzle.config.ts')\n if (safeWriteFile(drizzleConfigPath, readTemplate('drizzle.config.ts'))) {\n created.push('drizzle.config.ts')\n }\n\n return created\n}\n","/**\n * Dependency installer: auto-install all required deps via detected package manager.\n * Splits into core (production) and dev dependencies.\n * Optionally includes email deps (resend + @react-email/components).\n * Uses async spawn so the clack spinner can animate during install.\n */\n\nimport { spawn } from 'node:child_process'\nimport type { PackageManager } from '../../utils/package-manager.js'\n\nexport interface InstallDepsOptions {\n cwd: string\n pm: PackageManager\n includeEmail: boolean\n includeBiome: boolean\n}\n\nexport interface InstallDepsResult {\n coreDeps: string[]\n devDeps: string[]\n success: boolean\n error: string | null\n}\n\n// ============================================================================\n// Dependency Lists\n// ============================================================================\n\n/** Core runtime deps — always installed */\nexport const CORE_DEPS = [\n // Database\n 'drizzle-orm',\n '@neondatabase/serverless',\n // Auth\n 'better-auth',\n // Data fetching + tables\n '@tanstack/react-query',\n '@tanstack/react-table',\n '@tanstack/react-virtual',\n // Forms + validation\n 'react-hook-form',\n '@hookform/resolvers',\n 'zod',\n // URL state + toast + theme\n 'nuqs',\n 'sonner',\n // Styling utilities\n 'geist',\n 'class-variance-authority',\n 'clsx',\n 'tailwind-merge',\n // Icons\n 'lucide-react',\n // Storage (R2)\n '@aws-sdk/client-s3',\n // Radix UI (unified package + legacy scoped packages)\n 'radix-ui',\n '@radix-ui/react-accordion',\n '@radix-ui/react-alert-dialog',\n '@radix-ui/react-aspect-ratio',\n '@radix-ui/react-avatar',\n '@radix-ui/react-checkbox',\n '@radix-ui/react-collapsible',\n '@radix-ui/react-context-menu',\n '@radix-ui/react-dialog',\n '@radix-ui/react-dropdown-menu',\n '@radix-ui/react-hover-card',\n '@radix-ui/react-label',\n '@radix-ui/react-menubar',\n '@radix-ui/react-navigation-menu',\n '@radix-ui/react-popover',\n '@radix-ui/react-progress',\n '@radix-ui/react-radio-group',\n '@radix-ui/react-scroll-area',\n '@radix-ui/react-select',\n '@radix-ui/react-separator',\n '@radix-ui/react-slider',\n '@radix-ui/react-slot',\n '@radix-ui/react-switch',\n '@radix-ui/react-tabs',\n '@radix-ui/react-toast',\n '@radix-ui/react-toggle',\n '@radix-ui/react-toggle-group',\n '@radix-ui/react-tooltip',\n // Rich text (TipTap)\n '@tiptap/core',\n '@tiptap/pm',\n '@tiptap/react',\n '@tiptap/starter-kit',\n '@tiptap/extension-highlight',\n '@tiptap/extension-horizontal-rule',\n '@tiptap/extension-image',\n '@tiptap/extension-list',\n '@tiptap/extension-placeholder',\n '@tiptap/extension-subscript',\n '@tiptap/extension-superscript',\n '@tiptap/extension-text-align',\n '@tiptap/extension-typography',\n '@tiptap/extensions',\n 'tiptap-markdown',\n '@floating-ui/react',\n 'react-hotkeys-hook',\n 'lodash.throttle',\n // CodeMirror markdown editor\n '@codemirror/lang-markdown',\n '@codemirror/view',\n '@uiw/codemirror-theme-github',\n '@uiw/react-codemirror',\n // Date\n 'date-fns',\n 'react-day-picker',\n // Markdown rendering\n 'shiki',\n '@shikijs/transformers',\n 'katex',\n 'markdown-it',\n // Drag-and-drop\n '@dnd-kit/core',\n '@dnd-kit/sortable',\n '@dnd-kit/utilities',\n // Other UI\n 'cmdk',\n 'embla-carousel-react',\n 'fuse.js',\n 'input-otp',\n 'react-resizable-panels',\n 'recharts',\n 'shadcn',\n 'tw-animate-css',\n 'usehooks-ts',\n 'vaul'\n]\n\n/** Email deps — only when email feature is enabled */\nexport const EMAIL_DEPS = ['resend', '@react-email/components']\n\n/** Mailchimp deps — always installed (fire-and-forget, no-op without env vars) */\nexport const MAILCHIMP_DEPS = ['@mailchimp/mailchimp_marketing']\n\n/** Mailchimp type definitions */\nexport const MAILCHIMP_DEV_DEPS = ['@types/mailchimp__mailchimp_marketing']\n\n/** Dev deps — always installed */\nexport const DEV_DEPS = ['drizzle-kit', 'tsx', 'sass', '@types/katex', '@types/markdown-it@13']\n\n/** Biome dev dep — only when no existing linter */\nexport const BIOME_DEV_DEPS = ['@biomejs/biome']\n\n// ============================================================================\n// Installer\n// ============================================================================\n\nfunction buildAddArgs(pm: PackageManager, deps: string[], dev: boolean): string[] {\n const devFlag = dev ? (pm === 'yarn' ? '--dev' : '-D') : ''\n\n switch (pm) {\n case 'pnpm':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n case 'yarn':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n case 'bun':\n return ['add', ...(devFlag ? [devFlag] : []), ...deps]\n default:\n return ['install', ...(devFlag ? [devFlag] : []), ...deps]\n }\n}\n\nfunction spawnAsync(cmd: string, args: string[], cwd: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { cwd, stdio: 'pipe' })\n let stderr = ''\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n child.on('close', (code) => {\n if (code === 0) resolve()\n else reject(new Error(stderr || `${cmd} exited with code ${code}`))\n })\n child.on('error', reject)\n })\n}\n\nexport async function installDependenciesAsync({\n cwd,\n pm,\n includeEmail,\n includeBiome\n}: InstallDepsOptions): Promise<InstallDepsResult> {\n const coreDeps = [...CORE_DEPS, ...MAILCHIMP_DEPS]\n if (includeEmail) coreDeps.push(...EMAIL_DEPS)\n\n const devDeps = [...DEV_DEPS, ...MAILCHIMP_DEV_DEPS]\n if (includeBiome) devDeps.push(...BIOME_DEV_DEPS)\n\n try {\n // Install core deps\n await spawnAsync(pm, buildAddArgs(pm, coreDeps, false), cwd)\n\n // Install dev deps\n await spawnAsync(pm, buildAddArgs(pm, devDeps, true), cwd)\n\n return { coreDeps, devDeps, success: true, error: null }\n } catch (err) {\n return {\n coreDeps,\n devDeps,\n success: false,\n error: err instanceof Error ? err.message : 'Install failed'\n }\n }\n}\n","import crypto from 'node:crypto'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { EnvSection } from '../../utils/env.js'\nimport { appendEnvVars } from '../../utils/env.js'\n\nexport function detectDevPort(cwd: string): number {\n const pkgPath = join(cwd, 'package.json')\n if (!existsSync(pkgPath)) return 3000\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {\n scripts?: Record<string, string>\n }\n const devScript = pkg.scripts?.dev ?? ''\n const match = devScript.match(/--port\\s+(\\d+)|-p\\s+(\\d+)/)\n if (match) {\n const port = Number.parseInt(match[1] ?? match[2], 10)\n if (port > 0 && port <= 65535) return port\n }\n } catch {\n // ignore parse errors\n }\n return 3000\n}\n\nfunction getCoreEnvSections(\n databaseUrl: string | undefined,\n devPort: number\n): EnvSection[] {\n const authSecret = crypto.randomBytes(32).toString('base64')\n return [\n {\n header: 'Database (Neon)',\n vars: [{ key: 'BETTERSTART_DATABASE_URL', value: databaseUrl ?? 'postgresql://...' }]\n },\n {\n header: 'Authentication',\n vars: [\n { key: 'BETTERSTART_AUTH_SECRET', value: authSecret },\n { key: 'BETTERSTART_AUTH_URL', value: `http://localhost:${devPort}` },\n { key: 'BETTERSTART_AUTH_BASE_PATH', value: '/api/cms/auth' }\n ]\n },\n {\n header: 'Storage (Cloudflare R2)',\n vars: [\n { key: 'BETTERSTART_R2_ACCOUNT_ID', value: '' },\n { key: 'BETTERSTART_R2_ACCESS_KEY_ID', value: '' },\n { key: 'BETTERSTART_R2_SECRET_ACCESS_KEY', value: '' },\n { key: 'BETTERSTART_R2_BUCKET_NAME', value: '' },\n { key: 'BETTERSTART_R2_PUBLIC_URL', value: '' }\n ]\n }\n ]\n}\n\nfunction getEmailEnvSection(): EnvSection {\n return {\n header: 'Email (Resend)',\n vars: [\n { key: 'BETTERSTART_RESEND_API_KEY', value: '' },\n { key: 'BETTERSTART_EMAIL_FROM', value: 'noreply@yourdomain.com' }\n ]\n }\n}\n\nfunction getMailchimpEnvSection(): EnvSection {\n return {\n header: 'Mailchimp (optional — leave blank to disable)',\n vars: [\n { key: 'BETTERSTART_MAILCHIMP_API_KEY', value: '' },\n { key: 'BETTERSTART_MAILCHIMP_SERVER_PREFIX', value: '' },\n { key: 'BETTERSTART_MAILCHIMP_AUDIENCE_ID', value: '' }\n ]\n }\n}\n\n/**\n * Append BETTERSTART_* environment variables to .env.local.\n */\nexport function scaffoldEnv(\n cwd: string,\n options: { includeEmail: boolean; databaseUrl?: string }\n): { added: string[]; skipped: string[]; updated: string[] } {\n const devPort = detectDevPort(cwd)\n const sections = getCoreEnvSections(options.databaseUrl, devPort)\n if (options.includeEmail) {\n sections.push(getEmailEnvSection())\n }\n sections.push(getMailchimpEnvSection())\n // If the user provided a real database URL, overwrite any existing placeholder\n const overwrite = options.databaseUrl ? new Set(['BETTERSTART_DATABASE_URL']) : undefined\n return appendEnvVars(cwd, sections, overwrite)\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface EnvVar {\n key: string\n value: string\n comment?: string\n}\n\nexport interface EnvSection {\n header: string\n vars: EnvVar[]\n}\n\n/**\n * Safely append environment variables to .env.local.\n * Never overwrites existing values — only adds missing keys.\n * Keys listed in `overwrite` will be updated even if they already exist.\n */\nexport function appendEnvVars(\n cwd: string,\n sections: EnvSection[],\n overwrite?: Set<string>\n): { added: string[]; skipped: string[]; updated: string[] } {\n const envPath = path.join(cwd, '.env.local')\n let existing = fs.existsSync(envPath) ? fs.readFileSync(envPath, 'utf-8') : ''\n\n const existingKeys = new Set(\n existing\n .split('\\n')\n .filter((line) => line.trim() && !line.trim().startsWith('#'))\n .map((line) => line.split('=')[0]?.trim())\n .filter(Boolean)\n )\n\n const added: string[] = []\n const skipped: string[] = []\n const updated: string[] = []\n const lines: string[] = []\n\n // In-place update for overwrite keys that already exist\n if (overwrite) {\n for (const section of sections) {\n for (const v of section.vars) {\n if (overwrite.has(v.key) && existingKeys.has(v.key)) {\n const pattern = new RegExp(`^${v.key}=.*$`, 'm')\n const replacement = v.comment\n ? `${v.key}=\"${v.value}\" # ${v.comment}`\n : `${v.key}=\"${v.value}\"`\n existing = existing.replace(pattern, replacement)\n updated.push(v.key)\n }\n }\n }\n }\n\n if (existing.trim()) {\n lines.push('')\n }\n\n for (const section of sections) {\n const sectionVars = section.vars.filter((v) => {\n if (existingKeys.has(v.key)) {\n if (!updated.includes(v.key)) skipped.push(v.key)\n return false\n }\n added.push(v.key)\n return true\n })\n\n if (sectionVars.length === 0) continue\n\n lines.push(`# ${section.header}`)\n for (const v of sectionVars) {\n const line = v.comment ? `${v.key}=\"${v.value}\" # ${v.comment}` : `${v.key}=\"${v.value}\"`\n lines.push(line)\n }\n lines.push('')\n }\n\n if (added.length > 0 || updated.length > 0) {\n const header = existing.trim()\n ? ''\n : '# ============================================\\n# BetterStart CMS\\n# ============================================\\n'\n const content = existing.trim()\n ? `${existing.trimEnd()}\\n${lines.join('\\n')}`\n : header + lines.join('\\n')\n fs.writeFileSync(envPath, content)\n }\n\n return { added, skipped, updated }\n}\n","import path from 'node:path'\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { ensureDir, safeWriteFile } from '../../utils/fs.js'\nimport { readTemplate } from '../templates/reader.js'\n\nexport interface LayoutScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n}\n\n/**\n * Create all CMS route structures: layouts, login, dashboard, users, settings.\n */\nexport function scaffoldLayout({ cwd, config }: LayoutScaffoldOptions): string[] {\n const created: string[] = []\n\n function write(relPath: string, content: string): void {\n const fullPath = path.resolve(cwd, relPath)\n ensureDir(path.dirname(fullPath))\n if (safeWriteFile(fullPath, content)) {\n created.push(relPath)\n }\n }\n\n // Derive base CMS layout dir from pages path\n // pages = \"./src/app/(cms)/cms/(authenticated)\" → cmsDir = \"./src/app/(cms)/cms\"\n const cmsDir = path.dirname(config.paths.pages)\n\n // --- Shared CMS layout ---\n write(path.join(cmsDir, 'layout.tsx'), readTemplate('pages/cms-layout.tsx'))\n\n // --- Authenticated layout ---\n write(path.join(config.paths.pages, 'layout.tsx'), readTemplate('pages/authenticated-layout.tsx'))\n\n // --- Login page ---\n write(path.join(config.paths.login, 'page.tsx'), readTemplate('pages/login-page.tsx'))\n write(path.join(config.paths.login, 'login-form.tsx'), readTemplate('pages/login-form.tsx'))\n\n // --- Dashboard ---\n write(path.join(config.paths.pages, 'page.tsx'), readTemplate('pages/dashboard-page.tsx'))\n\n // --- Users pages ---\n const usersDir = path.join(config.paths.pages, 'users')\n write(path.join(usersDir, 'page.tsx'), readTemplate('pages/users/users-page.tsx'))\n write(path.join(usersDir, 'users-page-content.tsx'), readTemplate('pages/users/users-page-content.tsx'))\n write(path.join(usersDir, 'users-table.tsx'), readTemplate('pages/users/users-table.tsx'))\n write(path.join(usersDir, 'columns.tsx'), readTemplate('pages/users/columns.tsx'))\n write(path.join(usersDir, 'create-user-dialog.tsx'), readTemplate('pages/users/create-user-dialog.tsx'))\n write(path.join(usersDir, 'edit-role-dialog.tsx'), readTemplate('pages/users/edit-role-dialog.tsx'))\n\n // --- Account layout + Profile page ---\n const accountDir = path.join(cmsDir, '(account)')\n write(path.join(accountDir, 'layout.tsx'), readTemplate('pages/account-layout.tsx'))\n\n const profileDir = path.join(accountDir, 'profile')\n write(path.join(profileDir, 'page.tsx'), readTemplate('pages/profile/profile-page.tsx'))\n write(path.join(profileDir, 'profile-form.tsx'), readTemplate('pages/profile/profile-form.tsx'))\n\n // --- Profile action + Sign-out component ---\n const cms = path.resolve(cwd, config.paths.cms)\n write(path.join(cms, 'lib', 'actions', 'profile.ts'), readTemplate('lib/actions/profile.ts'))\n write(path.join(cms, 'components', 'layout', 'cms-sign-out.tsx'), readTemplate('components/layout/cms-sign-out.tsx'))\n\n return created\n}\n","/**\n * Preset scaffolder: copy preset schemas into cms/schemas/ and run generate\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { BetterstartConfig } from '../../config/types.js'\nimport { runFormPipeline } from '../../generators/form-pipeline/index.js'\nimport { runEntityPipeline, runSinglePipeline } from '../../generators/index.js'\nimport type { FormSchema, Schema } from '../../types.js'\nimport type { Preset } from '../prompts/features.js'\nimport { blogCategoriesSchema } from '../templates/presets/blog-categories.js'\nimport { blogPostsSchema } from '../templates/presets/blog-posts.js'\nimport { defaultSettingsSchema } from '../templates/presets/default-settings.js'\nimport { fullContactSchema } from '../templates/presets/full-contact.js'\nimport { fullNavigationSchema } from '../templates/presets/full-navigation.js'\n\nexport interface PresetScaffoldOptions {\n cwd: string\n config: BetterstartConfig\n preset: Preset\n}\n\nexport interface PresetScaffoldResult {\n schemas: string[]\n generatedFiles: string[]\n errors: string[]\n}\n\ninterface PresetSchema {\n filename: string\n content: string\n isForm: boolean\n isSingle: boolean\n}\n\nfunction getPresetSchemas(preset: Preset): PresetSchema[] {\n // Settings schema is always included (even for blank preset)\n const schemas: PresetSchema[] = [\n {\n filename: 'settings.json',\n content: defaultSettingsSchema(),\n isForm: false,\n isSingle: true\n }\n ]\n\n if (preset !== 'blank') {\n schemas.push(\n {\n filename: 'categories.json',\n content: blogCategoriesSchema(),\n isForm: false,\n isSingle: false\n },\n { filename: 'posts.json', content: blogPostsSchema(), isForm: false, isSingle: false }\n )\n }\n\n if (preset === 'full') {\n schemas.push(\n {\n filename: 'navigation.json',\n content: fullNavigationSchema(),\n isForm: false,\n isSingle: false\n },\n {\n filename: 'forms/contact.json',\n content: fullContactSchema(),\n isForm: true,\n isSingle: false\n }\n )\n }\n\n return schemas\n}\n\n/**\n * Apply preset: write schema files and run entity generation for each\n */\nexport function scaffoldPreset({\n cwd,\n config,\n preset\n}: PresetScaffoldOptions): PresetScaffoldResult {\n const result: PresetScaffoldResult = {\n schemas: [],\n generatedFiles: [],\n errors: []\n }\n\n const schemasDir = path.join(cwd, config.paths?.schemas ?? './cms/schemas')\n const presetSchemas = getPresetSchemas(preset)\n\n // 1. Write all schema files first\n for (const ps of presetSchemas) {\n const filePath = path.join(schemasDir, ps.filename)\n const dir = path.dirname(filePath)\n\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n\n fs.writeFileSync(filePath, ps.content, 'utf-8')\n result.schemas.push(ps.filename)\n }\n\n // 2. Run pipelines for each schema\n for (const ps of presetSchemas) {\n try {\n if (ps.isForm) {\n const schema = JSON.parse(ps.content) as FormSchema\n const pipelineResult = runFormPipeline(schema, cwd, config, { force: true, silent: true })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n } else if (ps.isSingle) {\n const schema = JSON.parse(ps.content) as Schema\n const pipelineResult = runSinglePipeline(schema, cwd, config, {\n force: true,\n silent: true\n })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n } else {\n const schema = JSON.parse(ps.content) as Schema\n const pipelineResult = runEntityPipeline(schema, cwd, config, {\n force: true,\n silent: true\n })\n result.generatedFiles.push(...pipelineResult.files)\n if (!pipelineResult.success) {\n result.errors.push(...pipelineResult.errors.map((e) => `${ps.filename}: ${e}`))\n }\n }\n } catch (err) {\n result.errors.push(`${ps.filename}: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n\n return result\n}\n","/**\n * Blog preset: categories.json schema\n * Simple entity with name, slug, description, color\n */\nexport function blogCategoriesSchema(): string {\n return JSON.stringify(\n {\n name: 'categories',\n label: 'Categories',\n description: 'Organize posts with categories',\n icon: 'Tag',\n navGroup: { label: 'Blog', icon: 'BookOpen' },\n fields: [\n {\n name: 'name',\n type: 'string',\n label: 'Name',\n required: true,\n hint: 'Category name'\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from name)',\n hidden: true\n },\n {\n name: 'description',\n type: 'text',\n label: 'Description',\n hint: 'Optional description of the category'\n },\n {\n name: 'color',\n type: 'string',\n label: 'Color',\n hint: 'Optional color code for UI display (e.g., #3B82F6)'\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'slug',\n header: 'Slug',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'description',\n header: 'Description',\n type: 'text',\n sortable: false\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true\n },\n search: {\n fields: ['name', 'description']\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'name',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","/**\n * Blog preset: posts.json schema\n * Entity with M2M relationship to categories, richtext content, auto-slugify\n */\nexport function blogPostsSchema(): string {\n return JSON.stringify(\n {\n name: 'posts',\n label: 'Posts',\n description: 'Manage blog posts and articles',\n icon: 'FileText',\n navGroup: { label: 'Blog', icon: 'BookOpen' },\n fields: [\n {\n name: 'title',\n type: 'string',\n label: 'Title',\n required: true\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from title)',\n hidden: true\n },\n {\n name: 'categories',\n type: 'relationship',\n relationship: 'categories',\n label: 'Categories',\n multiple: true,\n hint: 'Assign one or more categories'\n },\n {\n name: 'excerpt',\n type: 'text',\n label: 'Excerpt',\n hint: 'Short summary for listing pages'\n },\n {\n name: 'coverImage',\n type: 'image',\n label: 'Cover Image'\n },\n {\n name: 'content',\n type: 'richtext',\n label: 'Content',\n output: 'html'\n }\n ],\n columns: [\n {\n accessorKey: 'title',\n header: 'Title',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'published',\n header: 'Status',\n type: 'boolean',\n sortable: true\n },\n {\n accessorKey: 'updatedAt',\n header: 'Updated',\n type: 'date',\n sortable: true\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true,\n draft: true\n },\n search: {\n fields: ['title', 'excerpt']\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'title',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","/**\n * Default settings schema (applied to ALL presets including blank)\n * Generates a singleton form at /cms/settings\n */\nexport function defaultSettingsSchema(): string {\n return JSON.stringify(\n {\n name: 'settings',\n type: 'single',\n label: 'Settings',\n description: 'General Settings',\n icon: 'Settings',\n fields: [\n {\n type: 'section',\n name: 'siteSettings',\n label: 'Site Settings',\n description: 'General settings for the site',\n fields: [\n { name: 'appName', type: 'string', label: 'App Name', hint: 'Displayed in the sidebar and throughout the dashboard', default: 'BetterStart' },\n { name: 'appDescription', type: 'text', label: 'App Description', hint: 'A brief description of the application' }\n ]\n },\n {\n type: 'section',\n name: 'branding',\n label: 'Branding',\n description: 'Logo and visual identity',\n fields: [\n { name: 'logo', type: 'image', label: 'Logo' }\n ]\n }\n ]\n },\n null,\n 2\n )\n}\n","/**\n * Full preset: contact.json form schema\n * Public contact form with admin submission viewer\n */\nexport function fullContactSchema(): string {\n return JSON.stringify(\n {\n name: 'contact',\n label: 'Contact Form',\n description: 'Website contact form submissions',\n icon: 'Mail',\n submitButtonText: 'Send Message',\n successMessage: \"Thank you! We'll get back to you soon.\",\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Full Name',\n placeholder: 'Jane Doe',\n required: true,\n minLength: 2,\n maxLength: 100\n },\n {\n name: 'email',\n type: 'email',\n label: 'Email Address',\n placeholder: 'jane@example.com',\n required: true\n },\n {\n name: 'subject',\n type: 'select',\n label: 'Subject',\n required: true,\n options: [\n { label: 'General Inquiry', value: 'general' },\n { label: 'Support', value: 'support' },\n { label: 'Feedback', value: 'feedback' },\n { label: 'Other', value: 'other' }\n ]\n },\n {\n name: 'message',\n type: 'textarea',\n label: 'Message',\n placeholder: 'How can we help?',\n required: true,\n minLength: 10\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'email',\n header: 'Email',\n type: 'email',\n sortable: true\n },\n {\n accessorKey: 'subject',\n header: 'Subject',\n type: 'badge',\n sortable: true\n },\n {\n accessorKey: 'submittedAt',\n header: 'Submitted',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n export: true,\n delete: true\n }\n },\n null,\n 2\n )\n}\n","/**\n * Full preset: navigation.json schema\n * Entity for managing website navigation menus with nested items\n */\nexport function fullNavigationSchema(): string {\n return JSON.stringify(\n {\n name: 'navigation',\n label: 'Navigation',\n description: 'Manage website navigation menus',\n icon: 'Navigation',\n fields: [\n {\n name: 'name',\n type: 'string',\n label: 'Name',\n required: true,\n hint: 'Navigation name (e.g., Main, Footer)'\n },\n {\n name: 'slug',\n type: 'string',\n label: 'Slug',\n hint: 'URL-friendly identifier (auto-generated from name)',\n hidden: true\n },\n {\n name: 'navItems',\n type: 'list',\n label: 'Navigation Items',\n fields: [\n {\n name: 'title',\n type: 'string',\n label: 'Title'\n },\n {\n name: 'url',\n type: 'string',\n label: 'URL Path'\n }\n ]\n }\n ],\n columns: [\n {\n accessorKey: 'name',\n header: 'Name',\n type: 'text',\n sortable: true\n },\n {\n accessorKey: 'createdAt',\n header: 'Created',\n type: 'date',\n sortable: true\n }\n ],\n actions: {\n create: true,\n edit: true,\n delete: true\n },\n autoSlugify: {\n enabled: true,\n sourceField: 'name',\n targetField: 'slug'\n }\n },\n null,\n 2\n )\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\nconst SOURCE_LINES = ['@source \"../cms/**/*.{ts,tsx}\";', '@source \"./(cms)/**/*.{ts,tsx}\";']\nconst SOURCE_LINES_SRC = ['@source \"../../cms/**/*.{ts,tsx}\";', '@source \"./(cms)/**/*.{ts,tsx}\";']\n\n// Tailwind v4 @theme tokens that map CSS vars to utility classes.\n// These let Tailwind generate bg-primary, text-muted-foreground, border-border, etc.\nconst CMS_THEME_BLOCK = `\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-input-border: var(--input-border);\n --color-ring: var(--ring);\n --color-chart-1: var(--chart-1);\n --color-chart-2: var(--chart-2);\n --color-chart-3: var(--chart-3);\n --color-chart-4: var(--chart-4);\n --color-chart-5: var(--chart-5);\n --color-sidebar: var(--sidebar);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-ring: var(--sidebar-ring);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n}`\n\n/**\n * Find the main CSS file that imports Tailwind.\n */\nfunction findMainCss(cwd: string): string | undefined {\n const candidates = [\n 'src/app/globals.css',\n 'app/globals.css',\n 'src/app/global.css',\n 'app/global.css',\n 'src/app/app.css',\n 'app/app.css',\n 'src/globals.css',\n 'globals.css'\n ]\n\n for (const candidate of candidates) {\n const filePath = path.join(cwd, candidate)\n if (fs.existsSync(filePath)) {\n return filePath\n }\n }\n return undefined\n}\n\n/**\n * Append @source directive and @theme tokens to the user's main CSS file\n * so Tailwind scans CMS component classes and generates utility classes.\n */\nexport function scaffoldTailwind(\n cwd: string,\n hasSrcDir: boolean\n): { file: string | null; appended: boolean } {\n const cssFile = findMainCss(cwd)\n if (!cssFile) {\n return { file: null, appended: false }\n }\n\n let content = fs.readFileSync(cssFile, 'utf-8')\n let changed = false\n\n // 1. Add @source directives if not present\n const sourceLines = hasSrcDir ? SOURCE_LINES_SRC : SOURCE_LINES\n const missingLines = sourceLines.filter((sl) => !content.includes(sl))\n if (missingLines.length > 0) {\n const lines = content.split('\\n')\n let insertIndex = 0\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i]!.trim()\n if (\n trimmed.startsWith('@import') ||\n trimmed.startsWith('@source') ||\n trimmed.startsWith('@plugin')\n ) {\n insertIndex = i + 1\n }\n }\n lines.splice(insertIndex, 0, ...missingLines)\n content = lines.join('\\n')\n changed = true\n }\n\n // 2. Add @theme tokens if not already present\n if (!content.includes('--color-primary')) {\n // If there's an existing @theme inline block, merge into it.\n // Otherwise append the full block at the end.\n const themeMatch = content.match(/@theme\\s+inline\\s*\\{/)\n if (themeMatch && themeMatch.index !== undefined) {\n // Find the closing brace of the existing @theme block\n let braceDepth = 0\n let insertPos = -1\n for (let i = themeMatch.index; i < content.length; i++) {\n if (content[i] === '{') braceDepth++\n if (content[i] === '}') {\n braceDepth--\n if (braceDepth === 0) {\n insertPos = i\n break\n }\n }\n }\n if (insertPos !== -1) {\n // Extract the existing @theme block content to avoid duplicates\n const existingBlock = content.slice(themeMatch.index, insertPos)\n const varsOnly = CMS_THEME_BLOCK.split('\\n')\n .filter((l) => l.trim().startsWith('--'))\n .filter((l) => {\n const varName = l.trim().split(':')[0]!.trim()\n return !existingBlock.includes(varName)\n })\n .map((l) => ` ${l.trim()}`)\n .join('\\n')\n if (varsOnly) {\n content = `${content.slice(0, insertPos)}${varsOnly}\\n${content.slice(insertPos)}`\n changed = true\n }\n }\n } else {\n // No existing @theme block — append the full block\n content = `${content}\\n${CMS_THEME_BLOCK}\\n`\n changed = true\n }\n }\n\n if (changed) {\n fs.writeFileSync(cssFile, content, 'utf-8')\n }\n\n return { file: cssFile, appended: changed }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\n\n// Strip line and block comments from JSON, respecting quoted strings.\nfunction stripJsonComments(input: string): string {\n let result = ''\n let i = 0\n while (i < input.length) {\n // Inside a string — copy until closing quote\n if (input[i] === '\"') {\n let j = i + 1\n while (j < input.length) {\n if (input[j] === '\\\\') {\n j += 2\n continue\n }\n if (input[j] === '\"') {\n j++\n break\n }\n j++\n }\n result += input.slice(i, j)\n i = j\n // Line comment\n } else if (input[i] === '/' && input[i + 1] === '/') {\n const nl = input.indexOf('\\n', i)\n i = nl === -1 ? input.length : nl\n // Block comment\n } else if (input[i] === '/' && input[i + 1] === '*') {\n const end = input.indexOf('*/', i + 2)\n i = end === -1 ? input.length : end + 2\n } else {\n result += input[i]\n i++\n }\n }\n return result\n}\n\nconst CMS_PATH_ALIASES: Record<string, string[]> = {\n '@cms/*': ['./cms/*'],\n '@cms/db': ['./cms/db/client'],\n '@cms/db/schema': ['./cms/db/schema'],\n '@cms/actions/*': ['./cms/lib/actions/*'],\n '@cms/auth': ['./cms/lib/auth/auth'],\n '@cms/auth/client': ['./cms/lib/auth/auth-client'],\n '@cms/auth/middleware': ['./cms/lib/auth/middleware'],\n '@cms/hooks/*': ['./cms/hooks/*'],\n '@cms/components/*': ['./cms/components/*'],\n '@cms/types': ['./cms/types'],\n '@cms/types/*': ['./cms/types/*'],\n '@cms/utils/*': ['./cms/utils/*'],\n '@cms/data/*': ['./cms/data/*'],\n '@cms/cache/*': ['./cms/lib/cache/*']\n}\n\n/**\n * Append @cms/* path aliases to tsconfig.json.\n * Preserves existing content and only adds missing aliases.\n */\nexport function scaffoldTsconfig(cwd: string): { added: string[]; skipped: string[] } {\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n const added: string[] = []\n const skipped: string[] = []\n\n if (!fs.existsSync(tsconfigPath)) {\n skipped.push('tsconfig.json not found')\n return { added, skipped }\n }\n\n const raw = fs.readFileSync(tsconfigPath, 'utf-8')\n\n // Strip JSON comments while preserving string contents.\n // Walks character-by-character to avoid mangling strings that contain /* or //.\n const stripped = stripJsonComments(raw)\n // Remove trailing commas before } or ]\n .replace(/,\\s*([\\]}])/g, '$1')\n\n let tsconfig: Record<string, unknown>\n try {\n tsconfig = JSON.parse(stripped)\n } catch {\n skipped.push('Failed to parse tsconfig.json')\n return { added, skipped }\n }\n\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<string, unknown>\n const paths = (compilerOptions.paths ?? {}) as Record<string, string[]>\n\n for (const [alias, target] of Object.entries(CMS_PATH_ALIASES)) {\n if (alias in paths) {\n skipped.push(alias)\n } else {\n paths[alias] = target\n added.push(alias)\n }\n }\n\n compilerOptions.paths = paths\n tsconfig.compilerOptions = compilerOptions\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`, 'utf-8')\n\n return { added, skipped }\n}\n","/**\n * seed command — create initial admin user via Better Auth\n *\n * Generates a seed script at cms/scripts/seed.ts and runs it with tsx.\n * The script uses Better Auth's server API to create the user, then\n * sets the role to 'admin' via a direct database update.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\n\nexport function buildSeedScript(): string {\n // Self-contained: inlines DB + auth setup so tsx doesn't need @cms/* aliases.\n // Only relative import is ../db/schema which uses npm packages only.\n return `/**\n * BetterStart CMS — Seed Script\n * Creates the initial admin user\n * AUTO-GENERATED — safe to delete after running\n */\n\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\n// Load .env.local (inline — avoids @next/env dependency)\nfor (const envFile of ['.env.local', '.env']) {\n try {\n const content = readFileSync(resolve(process.cwd(), envFile), 'utf-8')\n for (const line of content.split('\\\\n')) {\n const trimmed = line.trim()\n if (!trimmed || trimmed.startsWith('#')) continue\n const eqIdx = trimmed.indexOf('=')\n if (eqIdx === -1) continue\n const key = trimmed.slice(0, eqIdx).trim()\n const val = trimmed.slice(eqIdx + 1).trim().replace(/^['\"]|['\"]$/g, '')\n if (!process.env[key]) process.env[key] = val\n }\n } catch {}\n}\n\nimport { neon } from '@neondatabase/serverless'\nimport { drizzle } from 'drizzle-orm/neon-http'\nimport { eq } from 'drizzle-orm'\nimport * as schema from '../db/schema'\nimport { betterAuth } from 'better-auth'\nimport { drizzleAdapter } from 'better-auth/adapters/drizzle'\n\n// Inline DB connection (mirrors cms/db/client.ts)\nconst sql = neon(process.env.BETTERSTART_DATABASE_URL!)\nconst db = drizzle({ client: sql, schema })\n\n// Inline auth setup (mirrors cms/lib/auth/auth.ts)\nconst auth = betterAuth({\n secret: process.env.BETTERSTART_AUTH_SECRET,\n baseURL: process.env.BETTERSTART_AUTH_URL,\n basePath: process.env.BETTERSTART_AUTH_BASE_PATH || '/api/cms/auth',\n database: drizzleAdapter(db, {\n provider: 'pg',\n schema: {\n user: schema.user,\n session: schema.session,\n account: schema.account,\n verification: schema.verification,\n },\n }),\n emailAndPassword: { enabled: true, minPasswordLength: 8 },\n user: {\n additionalFields: {\n role: { type: 'string', required: false, defaultValue: 'member', input: false },\n },\n },\n})\n\nconst EMAIL = process.env.SEED_EMAIL!\nconst PASSWORD = process.env.SEED_PASSWORD!\nconst NAME = process.env.SEED_NAME || 'Admin'\nconst OVERWRITE = process.env.SEED_OVERWRITE === 'true'\n\nasync function main() {\n // Check if user already exists\n const existing = await db\n .select({ id: schema.user.id, name: schema.user.name })\n .from(schema.user)\n .where(eq(schema.user.email, EMAIL))\n .then((rows: { id: string; name: string }[]) => rows[0])\n\n if (existing && !OVERWRITE) {\n // Exit code 2 signals \"user exists\" to the CLI\n console.log(\\`EXISTING_USER:\\${existing.name}\\`)\n process.exit(2)\n }\n\n if (existing && OVERWRITE) {\n console.log('\\\\n Replacing existing admin user...')\n // Remove existing account + session rows first (foreign key refs)\n await db.delete(schema.session).where(eq(schema.session.userId, existing.id))\n await db.delete(schema.account).where(eq(schema.account.userId, existing.id))\n await db.delete(schema.user).where(eq(schema.user.id, existing.id))\n } else {\n console.log('\\\\n Creating admin user...')\n }\n\n console.log(\\` Email: \\${EMAIL}\\\\n\\`)\n\n const result = await auth.api.signUpEmail({\n body: { email: EMAIL, password: PASSWORD, name: NAME },\n })\n\n if (!result?.user) {\n console.error(' Failed to create user.')\n process.exit(1)\n }\n\n await db\n .update(schema.user)\n .set({ role: 'admin' })\n .where(eq(schema.user.id, result.user.id))\n\n console.log(\\` Admin user \\${existing ? 'replaced' : 'created'}: \\${EMAIL}\\`)\n console.log(' Role: admin\\\\n')\n process.exit(0)\n}\n\nmain().catch((err) => {\n console.error(' Seed failed:', err.message || err)\n process.exit(1)\n})\n`\n}\n\nexport const seedCommand = new Command('seed')\n .description('Create the initial admin user')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Seed')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n clack.cancel(`Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const cmsDir = config.paths?.cms ?? './cms'\n\n // Prompt for user details\n const email = await clack.text({\n message: 'Admin email',\n placeholder: 'admin@example.com',\n validate: (v) => {\n if (!v || !v.includes('@')) return 'Please enter a valid email'\n }\n })\n if (clack.isCancel(email)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n const password = await clack.password({\n message: 'Admin password',\n validate: (v) => {\n if (!v || v.length < 8) return 'Password must be at least 8 characters'\n }\n })\n if (clack.isCancel(password)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n const name = await clack.text({\n message: 'Admin name',\n placeholder: 'Admin',\n defaultValue: 'Admin'\n })\n if (clack.isCancel(name)) {\n clack.cancel('Cancelled.')\n process.exit(0)\n }\n\n // Write seed script\n const scriptsDir = path.join(cwd, cmsDir, 'scripts')\n const seedPath = path.join(scriptsDir, 'seed.ts')\n\n if (!fs.existsSync(scriptsDir)) {\n fs.mkdirSync(scriptsDir, { recursive: true })\n }\n fs.writeFileSync(seedPath, buildSeedScript(), 'utf-8')\n\n const { execFile } = await import('node:child_process')\n const tsxBin = path.join(cwd, 'node_modules', '.bin', 'tsx')\n\n const runSeed = (overwrite: boolean) =>\n new Promise<{ code: number; stdout: string }>((resolve, reject) => {\n execFile(\n tsxBin,\n [seedPath],\n {\n cwd,\n env: {\n ...process.env,\n SEED_EMAIL: email,\n SEED_PASSWORD: password,\n SEED_NAME: name || 'Admin',\n ...(overwrite ? { SEED_OVERWRITE: 'true' } : {})\n }\n },\n (err, stdout, stderr) => {\n if (err && 'code' in err && err.code === 2) {\n // Exit code 2 = user already exists\n resolve({ code: 2, stdout })\n } else if (err) {\n reject(new Error(stderr || err.message))\n } else {\n resolve({ code: 0, stdout })\n }\n }\n )\n })\n\n const spinner = clack.spinner()\n spinner.start('Creating admin user...')\n\n try {\n const result = await runSeed(false)\n\n if (result.code === 2) {\n // User already exists — ask to overwrite\n const existingName =\n result.stdout\n .split('\\n')\n .find((l) => l.startsWith('EXISTING_USER:'))\n ?.replace('EXISTING_USER:', '')\n ?.trim() || 'unknown'\n\n spinner.stop(`Account already exists for ${email}`)\n\n const overwrite = await clack.confirm({\n message: `An admin account (${existingName}) already exists with this email. Replace it?`\n })\n if (clack.isCancel(overwrite) || !overwrite) {\n clack.cancel('Seed cancelled.')\n // Clean up before exiting\n try {\n fs.unlinkSync(seedPath)\n } catch {}\n process.exit(0)\n }\n\n spinner.start('Replacing admin user...')\n await runSeed(true)\n spinner.stop('Admin user replaced')\n } else {\n spinner.stop('Admin user created')\n }\n } catch (err) {\n spinner.stop('Failed to create admin user')\n\n const errMsg = err instanceof Error ? err.message : String(err)\n clack.log.error(errMsg)\n clack.log.info('You can run the seed script manually:')\n clack.log.info(\n ` SEED_EMAIL=\"${email}\" SEED_PASSWORD=\"...\" npx tsx ${path.relative(cwd, seedPath)}`\n )\n clack.outro('')\n process.exit(1)\n }\n\n // Clean up seed script\n try {\n fs.unlinkSync(seedPath)\n // Remove scripts dir if empty\n if (fs.existsSync(scriptsDir) && fs.readdirSync(scriptsDir).length === 0) {\n fs.rmdirSync(scriptsDir)\n }\n } catch {\n // Not critical\n }\n\n clack.outro(`Admin user ready: ${email}`)\n })\n","/**\n * remove command — delete generated files, clean schema.ts + navigation.ts\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport readline from 'node:readline'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport type { BetterstartConfig } from '../config/types.js'\nimport { toCamelCase, singularize, toKebabCase } from '../utils/string.js'\n\n// ============================================================================\n// Schema.ts Cleaning\n// ============================================================================\n\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prev = i > 0 ? content[i - 1] : ''\n\n if ((char === '\"' || char === \"'\" || char === '`') && prev !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n if (depth === 0 && char === ')') {\n // Skip trailing newlines\n let end = i + 1\n while (end < content.length && content[end] === '\\n') end++\n return end\n }\n }\n return content.length\n}\n\nfunction removeTableFromSchema(schemaFilePath: string, name: string): boolean {\n if (!fs.existsSync(schemaFilePath)) return false\n\n let content = fs.readFileSync(schemaFilePath, 'utf-8')\n const variableName = toCamelCase(name)\n let changed = false\n\n // Remove main table\n if (content.includes(`export const ${variableName} =`)) {\n const start = content.indexOf(`export const ${variableName} =`)\n const end = findTableEnd(content, start)\n content = content.slice(0, start) + content.slice(end)\n changed = true\n }\n\n // Remove junction tables (e.g., postCategories for posts schema)\n const singular = singularize(name)\n const junctionPrefix = toCamelCase(singular)\n // Find all exports starting with the singular prefix that are pgTable calls\n const regex = new RegExp(`export const (${junctionPrefix}[A-Z]\\\\w*) = pgTable\\\\(`, 'g')\n let jMatch = regex.exec(content)\n while (jMatch) {\n const jVarName = jMatch[1]\n const jStart = content.indexOf(`export const ${jVarName} =`)\n if (jStart !== -1) {\n const jEnd = findTableEnd(content, jStart)\n content = content.slice(0, jStart) + content.slice(jEnd)\n changed = true\n // Reset regex since content changed\n regex.lastIndex = 0\n jMatch = regex.exec(content)\n } else {\n jMatch = regex.exec(content)\n }\n }\n\n if (changed) {\n // Clean up multiple blank lines\n content = content.replace(/\\n{3,}/g, '\\n\\n')\n fs.writeFileSync(schemaFilePath, content, 'utf-8')\n }\n\n return changed\n}\n\n// ============================================================================\n// Navigation.ts Cleaning\n// ============================================================================\n\nfunction removeFromNavigation(navFilePath: string, name: string): boolean {\n if (!fs.existsSync(navFilePath)) return false\n\n const content = fs.readFileSync(navFilePath, 'utf-8')\n const href = `/cms/${name}`\n\n if (!content.includes(`'${href}'`)) return false\n\n // Flat structure: find the { ... } block containing this href\n const lines = content.split('\\n')\n let startLine = -1\n let endLine = -1\n let depth = 0\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n\n if (startLine === -1 && line.includes(`'${href}'`)) {\n // Walk back to find the opening `{`\n for (let j = i; j >= 0; j--) {\n if (lines[j].trim().startsWith('{')) {\n startLine = j\n break\n }\n }\n }\n\n if (startLine !== -1 && i >= startLine) {\n for (const char of line) {\n if (char === '{') depth++\n if (char === '}') depth--\n }\n if (depth === 0 && line.includes('}')) {\n endLine = i\n break\n }\n }\n }\n\n if (startLine === -1 || endLine === -1) return false\n\n lines.splice(startLine, endLine - startLine + 1)\n\n // Clean up double commas or leading commas\n const updated = lines\n .join('\\n')\n .replace(/,\\s*,/g, ',')\n .replace(/\\[\\s*,/, '[')\n fs.writeFileSync(navFilePath, updated, 'utf-8')\n return true\n}\n\n// ============================================================================\n// Confirmation\n// ============================================================================\n\nasync function promptConfirm(message: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n })\n return new Promise((resolve) => {\n rl.question(`${message} (y/N) `, (answer) => {\n rl.close()\n resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes')\n })\n })\n}\n\n// ============================================================================\n// Command\n// ============================================================================\n\nexport const removeCommand = new Command('remove')\n .alias('rm')\n .description('Remove all generated files for an entity or form')\n .argument('<schema>', 'Schema name to remove (e.g. posts, categories, contact)')\n .option('-f, --force', 'Skip confirmation prompt', false)\n .option('--cwd <path>', 'Project root path')\n .action(async (schemaName: string, options: { force: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n console.log('\\n BetterStart Remove\\n')\n\n // Load config\n let config: BetterstartConfig\n try {\n config = await resolveConfig(cwd)\n } catch (err) {\n console.error(` Error loading config: ${err instanceof Error ? err.message : String(err)}`)\n process.exit(1)\n }\n\n const cmsDir = config.paths?.cms ?? './cms'\n const pagesDir = config.paths?.pages ?? './src/app/(cms)/cms/(authenticated)'\n const kebabName = toKebabCase(schemaName)\n\n // Collect files/dirs to remove\n const targets: { path: string; label: string; isDir: boolean }[] = []\n\n // Pages directory\n const entityPagesDir = path.join(cwd, pagesDir, schemaName)\n if (fs.existsSync(entityPagesDir)) {\n targets.push({\n path: entityPagesDir,\n label: `${path.join(pagesDir, schemaName)}/`,\n isDir: true\n })\n }\n\n // Actions directory (new format) or single file (legacy format)\n const actionsDir = path.join(cwd, cmsDir, 'lib', 'actions', kebabName)\n const actionsFile = path.join(cwd, cmsDir, 'lib', 'actions', `${kebabName}.ts`)\n if (fs.existsSync(actionsDir)) {\n targets.push({\n path: actionsDir,\n label: `${path.join(cmsDir, 'lib', 'actions', kebabName)}/`,\n isDir: true\n })\n } else if (fs.existsSync(actionsFile)) {\n targets.push({\n path: actionsFile,\n label: path.join(cmsDir, 'lib', 'actions', `${kebabName}.ts`),\n isDir: false\n })\n }\n\n // Hook file\n const hookFile = path.join(cwd, cmsDir, 'hooks', `use-${kebabName}.ts`)\n if (fs.existsSync(hookFile)) {\n targets.push({\n path: hookFile,\n label: path.join(cmsDir, 'hooks', `use-${kebabName}.ts`),\n isDir: false\n })\n }\n\n // Check schema.ts for table entry\n const schemaFilePath = path.join(cwd, cmsDir, 'db', 'schema.ts')\n const hasTable =\n fs.existsSync(schemaFilePath) &&\n fs.readFileSync(schemaFilePath, 'utf-8').includes(`export const ${toCamelCase(schemaName)} =`)\n\n // Check navigation.ts for entry\n const navFilePath = path.join(cwd, cmsDir, 'data', 'navigation.ts')\n const hasNavEntry =\n fs.existsSync(navFilePath) &&\n fs.readFileSync(navFilePath, 'utf-8').includes(`'/cms/${schemaName}'`)\n\n if (targets.length === 0 && !hasTable && !hasNavEntry) {\n console.log(` No generated files found for: ${schemaName}`)\n return\n }\n\n // Show what will be removed\n console.log(' Files to remove:\\n')\n for (const t of targets) {\n console.log(` ${t.isDir ? '[dir]' : ' '} ${t.label}`)\n }\n if (hasTable) {\n console.log(` [edit] ${path.join(cmsDir, 'db', 'schema.ts')} (remove table)`)\n }\n if (hasNavEntry) {\n console.log(` [edit] ${path.join(cmsDir, 'data', 'navigation.ts')} (remove entry)`)\n }\n\n // Confirm\n if (!options.force) {\n console.log('')\n const confirmed = await promptConfirm(' Are you sure?')\n if (!confirmed) {\n console.log('\\n Cancelled.\\n')\n return\n }\n }\n\n console.log('')\n\n // Delete files/dirs\n for (const t of targets) {\n if (t.isDir) {\n fs.rmSync(t.path, { recursive: true, force: true })\n } else {\n fs.unlinkSync(t.path)\n }\n console.log(` Removed: ${t.label}`)\n }\n\n // Clean schema.ts\n if (hasTable) {\n removeTableFromSchema(schemaFilePath, schemaName)\n console.log(` Cleaned: ${path.join(cmsDir, 'db', 'schema.ts')}`)\n }\n\n // Clean navigation.ts\n if (hasNavEntry) {\n removeFromNavigation(navFilePath, schemaName)\n console.log(` Cleaned: ${path.join(cmsDir, 'data', 'navigation.ts')}`)\n }\n\n console.log('\\n Removal complete!')\n console.log('\\n Note: You may need to manually:')\n console.log(' - Run a migration to drop the database table')\n console.log(' - Remove the schema file from cms/schemas/')\n console.log(' - Regenerate the cache module (betterstart generate <any-schema>)')\n console.log('')\n })\n","/**\n * setup-r2 command — create a Cloudflare R2 bucket and configure env vars\n *\n * 1. Checks for wrangler CLI\n * 2. Ensures user is logged in to Cloudflare\n * 3. Creates an R2 bucket\n * 4. Enables the r2.dev public URL automatically via CF API\n * 5. Opens the dashboard for API token creation\n * 6. Prompts for credentials and writes them to .env.local\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\n\nimport { appendEnvVars } from '../utils/env.js'\n\nexport const setupR2Command = new Command('setup-r2')\n .description('Create a Cloudflare R2 bucket and configure storage env vars')\n .option('--cwd <path>', 'Project root path')\n .option('--bucket <name>', 'Bucket name (skips prompt)')\n .action(async (options: { cwd?: string; bucket?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n p.intro(pc.bgCyan(pc.black(' BetterStart — R2 Storage Setup ')))\n\n const s = p.spinner()\n\n // 1. Check for wrangler\n s.start('Looking for wrangler CLI')\n const wrangler = findWrangler(cwd)\n if (!wrangler) {\n s.stop(`${pc.red('✗')} Wrangler CLI not found`)\n p.log.error(\n `Install it first:\\n ${pc.cyan('npm install -g wrangler')}\\n ${pc.dim('or')} ${pc.cyan('npx wrangler --version')}`\n )\n process.exit(1)\n }\n s.stop(`Wrangler: ${pc.cyan(wrangler.bin === 'npx' ? 'npx wrangler' : 'wrangler')}`)\n\n // 2. Check auth / prompt login\n s.start('Checking Cloudflare authentication')\n const whoami = runWrangler(wrangler, ['whoami'], { cwd })\n const whoamiOut = whoami.stdout?.toString() ?? ''\n\n if (whoami.status !== 0 || whoamiOut.includes('Not authenticated')) {\n s.stop(`${pc.yellow('▲')} Not logged in to Cloudflare`)\n const login = await p.confirm({\n message: 'Open browser to log in to Cloudflare?',\n initialValue: true,\n })\n if (p.isCancel(login) || !login) {\n p.cancel('Setup cancelled. Run `wrangler login` manually first.')\n process.exit(0)\n }\n\n s.start('Waiting for Cloudflare login')\n const loginResult = runWrangler(wrangler, ['login'], { cwd, stdio: 'inherit', timeout: 120_000 })\n if (loginResult.status !== 0) {\n s.stop(`${pc.red('✗')} Login failed`)\n p.cancel('Could not authenticate with Cloudflare. Run `wrangler login` manually.')\n process.exit(1)\n }\n s.stop(`${pc.green('✓')} Logged in to Cloudflare`)\n } else {\n // Table format: \"│ Peiris@kasun.io's Account │ <id> │\"\n // Or \"associated with the email user@example.com\"\n const emailMatch = whoamiOut.match(/associated with the email\\s+(\\S+)/i)\n const tableMatch = whoamiOut.match(/│\\s*([^│]+?)\\s*│\\s*[a-f0-9]{32}\\s*│/)\n const accountLabel = emailMatch?.[1] ?? tableMatch?.[1]?.trim() ?? 'authenticated'\n s.stop(`Logged in as ${pc.cyan(accountLabel)}`)\n }\n\n // 3. Get account ID\n s.start('Fetching account ID')\n const accountId = extractAccountId(wrangler, cwd)\n if (!accountId) {\n s.stop(`${pc.red('✗')} Could not determine account ID`)\n p.log.info(\n `You can find it at: ${pc.cyan('https://dash.cloudflare.com/?to=/:account/r2')}`\n )\n process.exit(1)\n }\n s.stop(`Account ID: ${pc.dim(accountId)}`)\n\n // 4. Prompt for bucket name\n let bucketName = options.bucket\n if (!bucketName) {\n const result = await p.text({\n message: 'R2 bucket name',\n placeholder: 'betterstart-uploads',\n defaultValue: 'betterstart-uploads',\n validate: (v) => {\n if (!v || v.length < 3) return 'Bucket name must be at least 3 characters'\n if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(v))\n return 'Bucket name must be lowercase alphanumeric with hyphens, no leading/trailing hyphens'\n },\n })\n if (p.isCancel(result)) {\n p.cancel('Setup cancelled.')\n process.exit(0)\n }\n bucketName = result\n }\n\n // 5. Create bucket\n s.start(`Creating R2 bucket: ${bucketName}`)\n\n const createResult = runWrangler(wrangler, ['r2', 'bucket', 'create', bucketName], {\n cwd,\n timeout: 30_000,\n })\n const createOut = (createResult.stdout?.toString() ?? '') + (createResult.stderr?.toString() ?? '')\n\n if (createResult.status !== 0) {\n if (createOut.includes('already exists') || createOut.includes('AlreadyExists')) {\n s.stop(`Bucket ${pc.cyan(bucketName)} already exists — using it`)\n } else {\n s.stop('Failed to create bucket')\n p.log.error(createOut.trim() || 'Unknown error from wrangler')\n process.exit(1)\n }\n } else {\n s.stop(`Created bucket: ${pc.cyan(bucketName)}`)\n }\n\n // 6. Enable r2.dev public URL automatically\n let publicUrl = ''\n const oauthToken = readWranglerToken()\n if (oauthToken) {\n s.start('Enabling public r2.dev URL')\n const domainResult = await enablePublicDomain(accountId, bucketName, oauthToken)\n if (domainResult.success && domainResult.domain) {\n publicUrl = `https://${domainResult.domain}`\n s.stop(`Public URL: ${pc.cyan(publicUrl)}`)\n } else {\n s.stop('Could not enable public URL automatically')\n p.log.warning(domainResult.error ?? 'Unknown error')\n p.log.info(\n `You can enable it manually in the dashboard:\\n ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/default/buckets/${bucketName}/settings`)}`\n )\n }\n } else {\n p.log.warning('Could not read wrangler OAuth token — skipping public URL setup')\n p.log.info(\n `Enable it manually: ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/default/buckets/${bucketName}/settings`)}`\n )\n }\n\n // 7. Prompt for S3-compatible API credentials\n p.note(\n [\n `Create an R2 API token with ${pc.bold('Object Read & Write')} permission.`,\n '',\n `Dashboard: ${pc.cyan(`https://dash.cloudflare.com/${accountId}/r2/api-tokens`)}`,\n '',\n pc.dim('The dashboard will give you an Access Key ID and Secret Access Key.'),\n ].join('\\n'),\n 'Create R2 API Token'\n )\n\n const openDashboard = await p.confirm({\n message: 'Open the R2 API tokens page in your browser?',\n initialValue: true,\n })\n if (!p.isCancel(openDashboard) && openDashboard) {\n const url = `https://dash.cloudflare.com/${accountId}/r2/api-tokens`\n try {\n execFileSync('open', [url], { stdio: 'pipe', timeout: 5_000 })\n } catch {\n p.log.warning(`Could not open browser. Visit: ${pc.cyan(url)}`)\n }\n }\n\n const credentials = await p.group(\n {\n accessKeyId: () =>\n p.text({\n message: 'R2 Access Key ID',\n placeholder: 'Paste from Cloudflare dashboard',\n validate: (v) => {\n if (!v || v.trim().length < 10) return 'Please paste a valid Access Key ID'\n },\n }),\n secretAccessKey: () =>\n p.password({\n message: 'R2 Secret Access Key',\n validate: (v) => {\n if (!v || v.trim().length < 10) return 'Please paste a valid Secret Access Key'\n },\n }),\n },\n {\n onCancel: () => {\n p.cancel('Setup cancelled.')\n process.exit(0)\n },\n }\n )\n\n // 8. Write env vars to .env.local\n s.start('Writing environment variables')\n const envResult = appendEnvVars(cwd, [\n {\n header: 'Storage (Cloudflare R2)',\n vars: [\n { key: 'BETTERSTART_R2_ACCOUNT_ID', value: accountId },\n { key: 'BETTERSTART_R2_ACCESS_KEY_ID', value: credentials.accessKeyId.trim() },\n { key: 'BETTERSTART_R2_SECRET_ACCESS_KEY', value: credentials.secretAccessKey.trim() },\n { key: 'BETTERSTART_R2_BUCKET_NAME', value: bucketName },\n ...(publicUrl ? [{ key: 'BETTERSTART_R2_PUBLIC_URL', value: publicUrl }] : []),\n ],\n },\n ], new Set([\n 'BETTERSTART_R2_ACCOUNT_ID',\n 'BETTERSTART_R2_ACCESS_KEY_ID',\n 'BETTERSTART_R2_SECRET_ACCESS_KEY',\n 'BETTERSTART_R2_BUCKET_NAME',\n 'BETTERSTART_R2_PUBLIC_URL',\n ]))\n\n const totalChanged = envResult.added.length + envResult.updated.length\n if (totalChanged > 0) {\n s.stop(`Updated .env.local ${pc.dim(`(${envResult.added.length} added, ${envResult.updated.length} updated)`)}`)\n } else {\n s.stop('All R2 env vars already set in .env.local')\n }\n\n // Summary\n const summaryLines = [\n `Bucket: ${pc.cyan(bucketName)}`,\n `Account: ${pc.dim(accountId)}`,\n `Access Key: ${pc.dim(credentials.accessKeyId.trim().slice(0, 8) + '...')}`,\n ]\n if (publicUrl) {\n summaryLines.push(`Public URL: ${pc.cyan(publicUrl)}`)\n }\n summaryLines.push(`Env file: ${pc.dim('.env.local')}`)\n\n p.note(summaryLines.join('\\n'), pc.green('R2 storage configured'))\n\n p.outro('Done! Your CMS can now upload files to R2.')\n })\n\ninterface WranglerRef {\n bin: string\n prefix: string[] // e.g. ['wrangler'] when using npx, [] when direct\n}\n\n/** Find wrangler binary — check local node_modules, global PATH, then npx */\nfunction findWrangler(cwd: string): WranglerRef | null {\n // Check local\n const localBin = path.join(cwd, 'node_modules', '.bin', 'wrangler')\n if (fs.existsSync(localBin)) return { bin: localBin, prefix: [] }\n\n // Check global via which\n const result = spawnSync('which', ['wrangler'], { stdio: 'pipe', timeout: 5_000 })\n if (result.status === 0) {\n const found = result.stdout?.toString().trim()\n if (found) return { bin: found, prefix: [] }\n }\n\n // Fall back to npx — just check it resolves (fast, no download)\n const npxResult = spawnSync('npx', ['wrangler', '--version'], {\n stdio: 'pipe',\n timeout: 15_000,\n })\n if (npxResult.status === 0) return { bin: 'npx', prefix: ['wrangler'] }\n\n return null\n}\n\n/** Run a wrangler command via the resolved ref */\nfunction runWrangler(\n ref: WranglerRef,\n args: string[],\n opts: { cwd: string; timeout?: number; stdio?: 'pipe' | 'inherit' }\n) {\n const fullArgs = [...ref.prefix, ...args]\n return spawnSync(ref.bin, fullArgs, {\n cwd: opts.cwd,\n stdio: opts.stdio ?? 'pipe',\n timeout: opts.timeout ?? 15_000,\n })\n}\n\n/** Extract account ID from wrangler whoami output */\nfunction extractAccountId(ref: WranglerRef, cwd: string): string | null {\n const result = runWrangler(ref, ['whoami'], { cwd })\n const output = result.stdout?.toString() ?? ''\n\n // wrangler whoami prints account ID in format: \"Account ID: <id>\"\n const idMatch = output.match(/Account ID[:\\s]+([a-f0-9]{32})/i)\n if (idMatch) return idMatch[1]\n\n // Table format: look for 32-char hex string\n const hexMatch = output.match(/\\b([a-f0-9]{32})\\b/)\n if (hexMatch) return hexMatch[1]\n\n return null\n}\n\n/** Read the OAuth token from wrangler's config file */\nfunction readWranglerToken(): string | null {\n // Wrangler stores config at platform-specific paths\n const candidates = [\n path.join(os.homedir(), 'Library', 'Preferences', '.wrangler', 'config', 'default.toml'), // macOS\n path.join(os.homedir(), '.config', '.wrangler', 'config', 'default.toml'), // Linux\n path.join(os.homedir(), '.wrangler', 'config', 'default.toml'), // fallback\n ]\n\n if (process.env.WRANGLER_CONFIG_PATH) {\n candidates.unshift(process.env.WRANGLER_CONFIG_PATH)\n }\n if (process.env.XDG_CONFIG_HOME) {\n candidates.unshift(\n path.join(process.env.XDG_CONFIG_HOME, '.wrangler', 'config', 'default.toml')\n )\n }\n\n for (const configPath of candidates) {\n if (!fs.existsSync(configPath)) continue\n try {\n const content = fs.readFileSync(configPath, 'utf-8')\n const match = content.match(/^oauth_token\\s*=\\s*\"([^\"]+)\"/m)\n if (match) return match[1]\n } catch {\n continue\n }\n }\n return null\n}\n\n/** Enable the r2.dev managed public domain on a bucket via Cloudflare API */\nasync function enablePublicDomain(\n accountId: string,\n bucketName: string,\n token: string\n): Promise<{ success: boolean; domain?: string; error?: string }> {\n try {\n const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/buckets/${bucketName}/domains/managed`\n const res = await fetch(url, {\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ enabled: true }),\n })\n const data = (await res.json()) as {\n success: boolean\n result?: { domain?: string; enabled?: boolean }\n errors?: Array<{ message: string }>\n }\n if (data.success && data.result?.domain) {\n return { success: true, domain: data.result.domain }\n }\n const errMsg = data.errors?.[0]?.message ?? 'API returned success=false'\n return { success: false, error: errMsg }\n } catch (err) {\n return { success: false, error: err instanceof Error ? err.message : 'fetch failed' }\n }\n}\n","/**\n * uninstall command — fully reverse everything `betterstart init` did.\n * Removes CMS directories, config files, path aliases, CSS modifications,\n * env vars, and dependencies from package.json.\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as p from '@clack/prompts'\nimport { Command } from 'commander'\nimport pc from 'picocolors'\nimport { cleanCss, cleanEnvFile, cleanTsconfig } from './uninstall-cleaners.js'\n\n// ============================================================================\n// CSS File Finder (shared logic with tailwind scaffolder)\n// ============================================================================\n\nfunction findMainCss(cwd: string): string | undefined {\n const candidates = [\n 'src/app/globals.css',\n 'app/globals.css',\n 'src/app/global.css',\n 'app/global.css',\n 'src/app/app.css',\n 'app/app.css',\n 'src/globals.css',\n 'globals.css'\n ]\n for (const candidate of candidates) {\n const filePath = path.join(cwd, candidate)\n if (fs.existsSync(filePath)) return filePath\n }\n return undefined\n}\n\n// ============================================================================\n// Biome Detection\n// ============================================================================\n\nfunction isCLICreatedBiome(biomePath: string): boolean {\n if (!fs.existsSync(biomePath)) return false\n try {\n const content = JSON.parse(fs.readFileSync(biomePath, 'utf-8'))\n // Check key structural markers that match our template\n return (\n content.$schema?.includes('biomejs.dev') &&\n content.formatter?.indentStyle === 'space' &&\n content.javascript?.formatter?.quoteStyle === 'single' &&\n Array.isArray(content.files?.ignore) &&\n content.files.ignore.includes('.next')\n )\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// Uninstall Plan\n// ============================================================================\n\ninterface UninstallStep {\n label: string\n items: string[]\n count: number\n unit: string\n execute: () => void\n}\n\nfunction buildUninstallPlan(cwd: string): UninstallStep[] {\n const steps: UninstallStep[] = []\n const hasSrc = fs.existsSync(path.join(cwd, 'src'))\n const appBase = hasSrc ? 'src/app' : 'app'\n\n // Step 1: CMS directories\n const dirs: string[] = []\n const cmsDir = path.join(cwd, 'cms')\n const cmsRouteGroup = path.join(cwd, appBase, '(cms)')\n if (fs.existsSync(cmsDir)) dirs.push('cms/')\n if (fs.existsSync(cmsRouteGroup)) dirs.push(`${appBase}/(cms)/`)\n\n if (dirs.length > 0) {\n steps.push({\n label: 'CMS directories',\n items: dirs,\n count: dirs.length,\n unit: dirs.length === 1 ? 'directory' : 'directories',\n execute() {\n if (fs.existsSync(cmsDir)) fs.rmSync(cmsDir, { recursive: true, force: true })\n if (fs.existsSync(cmsRouteGroup)) fs.rmSync(cmsRouteGroup, { recursive: true, force: true })\n }\n })\n }\n\n // Step 2: Config files\n const configFiles: string[] = []\n const configPaths: string[] = []\n const candidates = [\n ['cms.config.ts', path.join(cwd, 'cms.config.ts')],\n ['drizzle.config.ts', path.join(cwd, 'drizzle.config.ts')],\n ['CMS.md', path.join(cwd, 'CMS.md')]\n ] as const\n\n for (const [label, fullPath] of candidates) {\n if (fs.existsSync(fullPath)) {\n configFiles.push(label)\n configPaths.push(fullPath)\n }\n }\n\n const biomePath = path.join(cwd, 'biome.json')\n if (isCLICreatedBiome(biomePath)) {\n configFiles.push('biome.json (CLI-created)')\n configPaths.push(biomePath)\n }\n\n if (configFiles.length > 0) {\n steps.push({\n label: 'Config files',\n items: configFiles,\n count: configFiles.length,\n unit: configFiles.length === 1 ? 'file' : 'files',\n execute() {\n for (const p of configPaths) {\n if (fs.existsSync(p)) fs.unlinkSync(p)\n }\n }\n })\n }\n\n // Step 3: tsconfig.json @cms/* aliases\n const tsconfigPath = path.join(cwd, 'tsconfig.json')\n if (fs.existsSync(tsconfigPath)) {\n const content = fs.readFileSync(tsconfigPath, 'utf-8')\n const aliasMatches = content.match(/\"@cms\\//g)\n if (aliasMatches && aliasMatches.length > 0) {\n const aliasCount = aliasMatches.length\n steps.push({\n label: 'tsconfig.json path aliases',\n items: [`@cms/* aliases in tsconfig.json`],\n count: aliasCount,\n unit: aliasCount === 1 ? 'alias' : 'aliases',\n execute() {\n cleanTsconfig(tsconfigPath)\n }\n })\n }\n }\n\n // Step 4: CSS @source lines\n const cssFile = findMainCss(cwd)\n if (cssFile) {\n const cssContent = fs.readFileSync(cssFile, 'utf-8')\n const sourceLines = cssContent\n .split('\\n')\n .filter((l) => /^@source\\s+\"[^\"]*cms[^\"]*\";\\s*$/.test(l))\n if (sourceLines.length > 0) {\n const relCss = path.relative(cwd, cssFile)\n steps.push({\n label: `CSS @source lines (${relCss})`,\n items: [`@source lines in ${relCss}`],\n count: sourceLines.length,\n unit: sourceLines.length === 1 ? 'line' : 'lines',\n execute() {\n cleanCss(cssFile)\n }\n })\n }\n }\n\n // Step 5: .env.local BETTERSTART_* vars\n const envPath = path.join(cwd, '.env.local')\n if (fs.existsSync(envPath)) {\n const envContent = fs.readFileSync(envPath, 'utf-8')\n const bsVars = envContent\n .split('\\n')\n .filter((l) => l.trim().match(/^BETTERSTART_\\w+=/))\n .map((l) => l.split('=')[0]!)\n if (bsVars.length > 0) {\n steps.push({\n label: '.env.local variables',\n items: ['BETTERSTART_* vars in .env.local'],\n count: bsVars.length,\n unit: bsVars.length === 1 ? 'variable' : 'variables',\n execute() {\n cleanEnvFile(envPath)\n }\n })\n }\n }\n\n return steps\n}\n\n// ============================================================================\n// Command\n// ============================================================================\n\nexport const uninstallCommand = new Command('uninstall')\n .description('Remove all CMS files and undo modifications made by betterstart init')\n .option('-f, --force', 'Skip all confirmation prompts', false)\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { force: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n p.intro(pc.bgRed(pc.white(' BetterStart Uninstall ')))\n\n // Build the plan\n const steps = buildUninstallPlan(cwd)\n\n if (steps.length === 0) {\n p.log.success(`${pc.green('✓')} Nothing to remove — project is already clean.`)\n p.outro('Done')\n return\n }\n\n // Show plan as a formatted note box\n const planLines = steps.map((step) => {\n const names = step.items.join(' ')\n const countLabel = pc.dim(`${step.count} ${step.unit}`)\n return `${pc.red('×')} ${names} ${countLabel}`\n })\n p.note(planLines.join('\\n'), 'Uninstall plan')\n\n // Single confirmation for everything\n if (!options.force) {\n const confirmed = await p.confirm({\n message: 'Proceed with uninstall?',\n initialValue: false\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.cancel('Uninstall cancelled.')\n process.exit(0)\n }\n }\n\n // Execute all steps with a single spinner\n const s = p.spinner()\n s.start(steps[0]!.label)\n for (const step of steps) {\n s.message(step.label)\n step.execute()\n }\n const parts = steps.map((step) => `${step.count} ${step.unit}`)\n s.stop(`Removed ${parts.join(', ')}`)\n\n p.note(pc.dim('Database tables were NOT dropped — drop them manually if needed.'), 'Next steps')\n\n p.outro('Uninstall complete')\n })\n","/**\n * Cleaner functions for `betterstart uninstall`.\n * Each function modifies a single file type and returns what was removed.\n */\n\nimport fs from 'node:fs'\n\n// ============================================================================\n// JSON Comment Stripper (shared with tsconfig scaffolder)\n// ============================================================================\n\nfunction stripJsonComments(input: string): string {\n let result = ''\n let i = 0\n while (i < input.length) {\n if (input[i] === '\"') {\n let j = i + 1\n while (j < input.length) {\n if (input[j] === '\\\\') {\n j += 2\n continue\n }\n if (input[j] === '\"') {\n j++\n break\n }\n j++\n }\n result += input.slice(i, j)\n i = j\n } else if (input[i] === '/' && input[i + 1] === '/') {\n const nl = input.indexOf('\\n', i)\n i = nl === -1 ? input.length : nl\n } else if (input[i] === '/' && input[i + 1] === '*') {\n const end = input.indexOf('*/', i + 2)\n i = end === -1 ? input.length : end + 2\n } else {\n result += input[i]\n i++\n }\n }\n return result\n}\n\n// ============================================================================\n// cleanTsconfig\n// ============================================================================\n\n/**\n * Remove all `@cms/*` path aliases from tsconfig.json.\n * Returns the list of removed alias keys.\n */\nexport function cleanTsconfig(tsconfigPath: string): string[] {\n if (!fs.existsSync(tsconfigPath)) return []\n\n const raw = fs.readFileSync(tsconfigPath, 'utf-8')\n const stripped = stripJsonComments(raw).replace(/,\\s*([\\]}])/g, '$1')\n\n let tsconfig: Record<string, unknown>\n try {\n tsconfig = JSON.parse(stripped)\n } catch {\n return []\n }\n\n const compilerOptions = (tsconfig.compilerOptions ?? {}) as Record<string, unknown>\n const paths = (compilerOptions.paths ?? {}) as Record<string, string[]>\n\n const removed: string[] = []\n for (const key of Object.keys(paths)) {\n if (key.startsWith('@cms/') || key === '@cms/*') {\n removed.push(key)\n delete paths[key]\n }\n }\n\n if (removed.length === 0) return []\n\n if (Object.keys(paths).length === 0) {\n compilerOptions.paths = undefined\n } else {\n compilerOptions.paths = paths\n }\n tsconfig.compilerOptions = compilerOptions\n\n fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\\n`, 'utf-8')\n return removed\n}\n\n// ============================================================================\n// cleanCss\n// ============================================================================\n\n/**\n * Remove @source lines containing \"cms\" from a CSS file.\n * Returns the removed lines.\n */\nexport function cleanCss(cssPath: string): string[] {\n if (!fs.existsSync(cssPath)) return []\n\n const content = fs.readFileSync(cssPath, 'utf-8')\n const lines = content.split('\\n')\n\n const sourcePattern = /^@source\\s+\"[^\"]*cms[^\"]*\";\\s*$/\n const removed: string[] = []\n const kept: string[] = []\n\n for (const line of lines) {\n if (sourcePattern.test(line)) {\n removed.push(line.trim())\n } else {\n kept.push(line)\n }\n }\n\n if (removed.length === 0) return []\n\n // Clean up resulting double blank lines\n const cleaned = kept.join('\\n').replace(/\\n{3,}/g, '\\n\\n')\n fs.writeFileSync(cssPath, cleaned, 'utf-8')\n return removed\n}\n\n// ============================================================================\n// cleanEnvFile\n// ============================================================================\n\n/**\n * Remove BETTERSTART_* vars and the BetterStart header block from .env.local.\n * Returns the removed variable names.\n */\nexport function cleanEnvFile(envPath: string): string[] {\n if (!fs.existsSync(envPath)) return []\n\n const content = fs.readFileSync(envPath, 'utf-8')\n const lines = content.split('\\n')\n const removed: string[] = []\n const kept: string[] = []\n\n // Track header block lines to remove\n const headerPattern = /^# =+$/\n const headerTextPattern = /^# BetterStart CMS$/\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const trimmed = line.trim()\n\n // Remove BETTERSTART_* variable lines\n if (trimmed.match(/^BETTERSTART_\\w+=/)) {\n const key = trimmed.split('=')[0]!\n removed.push(key)\n continue\n }\n\n // Remove header block: # ====... / # BetterStart CMS / # ====...\n if (headerPattern.test(trimmed)) {\n const next = lines[i + 1]?.trim()\n const afterNext = lines[i + 2]?.trim()\n if (next && headerTextPattern.test(next) && afterNext && headerPattern.test(afterNext)) {\n i += 2 // skip all 3 header lines\n continue\n }\n }\n\n // Remove section comment headers that only precede BETTERSTART_ vars\n // e.g., \"# Database (Neon)\" followed by BETTERSTART_DATABASE_URL\n if (trimmed.startsWith('#') && !headerPattern.test(trimmed)) {\n const nextNonEmpty = findNextNonEmptyLine(lines, i + 1)\n if (nextNonEmpty?.match(/^BETTERSTART_\\w+=/)) {\n continue // skip this comment header\n }\n }\n\n kept.push(line)\n }\n\n if (removed.length === 0) return []\n\n // Clean up multiple blank lines\n const result = kept\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n\n if (result === '') {\n // File is now empty — delete it\n fs.unlinkSync(envPath)\n } else {\n fs.writeFileSync(envPath, `${result}\\n`, 'utf-8')\n }\n\n return removed\n}\n\nfunction findNextNonEmptyLine(lines: string[], startIndex: number): string | null {\n for (let i = startIndex; i < lines.length; i++) {\n const trimmed = lines[i]!.trim()\n if (trimmed !== '') return trimmed\n }\n return null\n}\n\n// ============================================================================\n// cleanPackageJsonDeps\n// ============================================================================\n\n/**\n * Remove CMS dependencies from package.json.\n * Returns the removed dep and devDep names.\n */\nexport function cleanPackageJsonDeps(\n pkgPath: string,\n allDeps: string[],\n allDevDeps: string[]\n): { removed: string[]; removedDev: string[] } {\n if (!fs.existsSync(pkgPath)) return { removed: [], removedDev: [] }\n\n const content = fs.readFileSync(pkgPath, 'utf-8')\n let pkg: Record<string, unknown>\n try {\n pkg = JSON.parse(content)\n } catch {\n return { removed: [], removedDev: [] }\n }\n\n const deps = (pkg.dependencies ?? {}) as Record<string, string>\n const devDeps = (pkg.devDependencies ?? {}) as Record<string, string>\n\n // Build lookup set: handle version-pinned names like @types/markdown-it@13 → @types/markdown-it\n const depNames = new Set(\n allDeps.map((d) =>\n d\n .split('@')\n .slice(0, d.startsWith('@') ? 2 : 1)\n .join('@')\n )\n )\n const devDepNames = new Set(\n allDevDeps.map((d) =>\n d\n .split('@')\n .slice(0, d.startsWith('@') ? 2 : 1)\n .join('@')\n )\n )\n\n const removed: string[] = []\n for (const name of Object.keys(deps)) {\n if (depNames.has(name)) {\n delete deps[name]\n removed.push(name)\n }\n }\n\n const removedDev: string[] = []\n for (const name of Object.keys(devDeps)) {\n if (devDepNames.has(name)) {\n delete devDeps[name]\n removedDev.push(name)\n }\n }\n\n if (removed.length === 0 && removedDev.length === 0) {\n return { removed: [], removedDev: [] }\n }\n\n pkg.dependencies = deps\n pkg.devDependencies = devDeps\n fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`, 'utf-8')\n\n return { removed, removedDev }\n}\n","/**\n * update-component command — update individual CMS components from the latest CLI templates\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport fsExtra from 'fs-extra'\nimport { resolveConfig } from '../config/resolver.js'\nimport { readTemplate } from '../init/templates/reader.js'\nimport { findCliRoot } from '../utils/cli-root.js'\n\ninterface TemplateEntry {\n relPath: string\n content: () => string\n base?: 'cwd'\n}\n\n/**\n * Template-function components (layout, shared, hooks, utils, etc.)\n * Key = component name used on CLI, value = { relative path in cms/, content generator }\n */\nconst TEMPLATE_REGISTRY: Record<string, TemplateEntry> = {\n // CSS\n 'cms-globals': { relPath: 'cms-globals.css', content: () => readTemplate('cms-globals.css') },\n // Layout\n 'cms-providers': { relPath: 'components/layout/cms-providers.tsx', content: () => readTemplate('components/layout/cms-providers.tsx') },\n 'cms-nav-link': { relPath: 'components/layout/cms-nav-link.tsx', content: () => readTemplate('components/layout/cms-nav-link.tsx') },\n 'cms-sidebar': { relPath: 'components/layout/cms-sidebar.tsx', content: () => readTemplate('components/layout/cms-sidebar.tsx') },\n 'cms-header': { relPath: 'components/layout/cms-header.tsx', content: () => readTemplate('components/layout/cms-header.tsx') },\n 'cms-search': { relPath: 'components/layout/cms-search.tsx', content: () => readTemplate('components/layout/cms-search.tsx') },\n 'cms-sign-out': { relPath: 'components/layout/cms-sign-out.tsx', content: () => readTemplate('components/layout/cms-sign-out.tsx') },\n // Shared\n 'page-header': { relPath: 'components/shared/page-header.tsx', content: () => readTemplate('components/shared/page-header.tsx') },\n 'delete-dialog': { relPath: 'components/shared/delete-dialog.tsx', content: () => readTemplate('components/shared/delete-dialog.tsx') },\n 'status-badge': { relPath: 'components/shared/status-badge.tsx', content: () => readTemplate('components/shared/status-badge.tsx') },\n // Data table\n 'data-table': { relPath: 'components/data-table/data-table.tsx', content: () => readTemplate('components/data-table/data-table.tsx') },\n 'data-table-pagination': { relPath: 'components/data-table/data-table-pagination.tsx', content: () => readTemplate('components/data-table/data-table-pagination.tsx') },\n 'data-table-toolbar': { relPath: 'components/data-table/data-table-toolbar.tsx', content: () => readTemplate('components/data-table/data-table-toolbar.tsx') },\n // Hooks\n 'use-upload': { relPath: 'hooks/use-upload.ts', content: () => readTemplate('hooks/use-upload.ts') },\n 'use-editor-image-upload': { relPath: 'hooks/use-editor-image-upload.ts', content: () => readTemplate('hooks/use-editor-image-upload.ts') },\n 'use-local-storage': { relPath: 'hooks/use-local-storage.ts', content: () => readTemplate('hooks/use-local-storage.ts') },\n 'use-cms-theme': { relPath: 'hooks/use-cms-theme.tsx', content: () => readTemplate('hooks/use-cms-theme.tsx') },\n 'use-users': { relPath: 'hooks/use-users.ts', content: () => readTemplate('hooks/use-users.ts') },\n 'use-mobile': { relPath: 'hooks/use-mobile.ts', content: () => readTemplate('hooks/use-mobile.ts') },\n // Types\n 'types-index': { relPath: 'types/index.ts', content: () => readTemplate('types/index.ts') },\n 'auth-types': { relPath: 'types/auth.ts', content: () => readTemplate('types/auth.ts') },\n 'table-meta': { relPath: 'types/table-meta.ts', content: () => readTemplate('types/table-meta.ts') },\n // Utils\n cn: { relPath: 'utils/cn.ts', content: () => readTemplate('utils/cn.ts') },\n seo: { relPath: 'utils/seo.ts', content: () => readTemplate('utils/seo.ts') },\n validation: { relPath: 'utils/validation.ts', content: () => readTemplate('utils/validation.ts') },\n webhook: { relPath: 'utils/webhook.ts', content: () => readTemplate('utils/webhook.ts') },\n mailchimp: { relPath: 'utils/mailchimp.ts', content: () => readTemplate('utils/mailchimp.ts') },\n // Auth\n 'auth-middleware': { relPath: 'lib/auth/middleware.ts', content: () => readTemplate('lib/auth/middleware.ts') },\n 'auth-layout': { relPath: 'app/(cms)/cms/(authenticated)/layout.tsx', content: () => readTemplate('pages/authenticated-layout.tsx'), base: 'cwd' },\n 'account-layout': { relPath: 'app/(cms)/cms/(account)/layout.tsx', content: () => readTemplate('pages/account-layout.tsx'), base: 'cwd' },\n 'profile-page': { relPath: 'app/(cms)/cms/(account)/profile/page.tsx', content: () => readTemplate('pages/profile/profile-page.tsx'), base: 'cwd' },\n 'profile-form': { relPath: 'app/(cms)/cms/(account)/profile/profile-form.tsx', content: () => readTemplate('pages/profile/profile-form.tsx'), base: 'cwd' },\n // Lib\n r2: { relPath: 'lib/r2.ts', content: () => readTemplate('lib/r2.ts') },\n 'form-settings-action': { relPath: 'lib/actions/form-settings.ts', content: () => readTemplate('lib/actions/form-settings.ts') },\n 'upload-action': { relPath: 'lib/actions/upload.ts', content: () => readTemplate('lib/actions/upload.ts') },\n 'users-action': { relPath: 'lib/actions/users.ts', content: () => readTemplate('lib/actions/users.ts') },\n 'profile-action': { relPath: 'lib/actions/profile.ts', content: () => readTemplate('lib/actions/profile.ts') },\n // Markdown\n 'markdown-render': { relPath: 'lib/markdown/render.ts', content: () => readTemplate('lib/markdown/render.ts') },\n 'markdown-format': { relPath: 'lib/markdown/format.ts', content: () => readTemplate('lib/markdown/format.ts') },\n 'markdown-cached': { relPath: 'lib/markdown/cached.ts', content: () => readTemplate('lib/markdown/cached.ts') },\n}\n\n/**\n * Get all available static UI component names from templates/ui/\n */\nfunction getStaticUiComponents(): string[] {\n const cliRoot = findCliRoot()\n const uiDir = path.join(cliRoot, 'templates', 'ui')\n if (!fs.existsSync(uiDir)) return []\n return fs\n .readdirSync(uiDir)\n .filter((f: string) => f.endsWith('.tsx') || f.endsWith('.ts'))\n .map((f: string) => f.replace(/\\.(tsx|ts)$/, ''))\n}\n\nfunction getAllComponentNames(): string[] {\n const staticUi = getStaticUiComponents()\n const templateKeys = Object.keys(TEMPLATE_REGISTRY)\n return [...new Set([...staticUi, ...templateKeys, 'tiptap'])].sort()\n}\n\nexport const updateComponentCommand = new Command('update')\n .alias('update-component')\n .description('Update CMS components from the latest CLI templates')\n .argument('[components...]', 'Component names to update (e.g., media-upload-field button)')\n .option('--list', 'List all available components')\n .option('--all', 'Update all components')\n .option('--cwd <path>', 'Project root path')\n .action(async (components: string[], options: { list?: boolean; all?: boolean; cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n if (options.list) {\n const all = getAllComponentNames()\n clack.intro('Available components')\n\n const uiComponents = getStaticUiComponents()\n const templateKeys = Object.keys(TEMPLATE_REGISTRY).sort()\n\n // UI components table\n console.log()\n console.log(` UI Components (${uiComponents.length})`)\n console.log(` ${'─'.repeat(50)}`)\n console.log(` ${'Name'.padEnd(28)} ${'Path'}`)\n console.log(` ${'─'.repeat(50)}`)\n for (const name of uiComponents) {\n console.log(` ${name.padEnd(28)} components/ui/${name}.tsx`)\n }\n\n // Template components table\n console.log()\n console.log(` Template Components (${templateKeys.length})`)\n console.log(` ${'─'.repeat(56)}`)\n console.log(` ${'Name'.padEnd(28)} ${'Path'}`)\n console.log(` ${'─'.repeat(56)}`)\n for (const name of templateKeys) {\n console.log(` ${name.padEnd(28)} ${TEMPLATE_REGISTRY[name].relPath}`)\n }\n\n // Special\n console.log()\n console.log(` Special`)\n console.log(` ${'─'.repeat(56)}`)\n console.log(` ${'tiptap'.padEnd(28)} components/ui/tiptap/ (all files)`)\n console.log()\n\n clack.outro(`${all.length} components available`)\n return\n }\n\n if (!options.all && components.length === 0) {\n clack.log.error('Provide component names or use --all. Run with --list to see available components.')\n process.exit(1)\n }\n\n const config = await resolveConfig(cwd)\n const cms = path.resolve(cwd, config.paths.cms)\n\n if (!fs.existsSync(cms)) {\n clack.cancel(`CMS directory not found at ${config.paths.cms}. Run 'betterstart init' first.`)\n process.exit(1)\n }\n\n clack.intro('BetterStart Update Components')\n\n const toUpdate = options.all ? getAllComponentNames() : components\n const cliRoot = findCliRoot()\n const uiDir = path.join(cliRoot, 'templates', 'ui')\n let updated = 0\n let skipped = 0\n\n for (const name of toUpdate) {\n // 1. Check template registry (template functions)\n if (TEMPLATE_REGISTRY[name]) {\n const entry = TEMPLATE_REGISTRY[name]\n const baseDir = entry.base === 'cwd' ? cwd : cms\n const destPath = path.join(baseDir, entry.relPath)\n fsExtra.ensureDirSync(path.dirname(destPath))\n fs.writeFileSync(destPath, entry.content(), 'utf-8')\n clack.log.success(`Updated ${entry.relPath}`)\n updated++\n continue\n }\n\n // 2. Check static UI templates\n const uiFile = fs.readdirSync(uiDir).find(\n (f: string) => f.replace(/\\.(tsx|ts)$/, '') === name,\n )\n if (uiFile) {\n const destPath = path.join(cms, 'components', 'ui', uiFile)\n fsExtra.ensureDirSync(path.dirname(destPath))\n fs.copyFileSync(path.join(uiDir, uiFile), destPath)\n clack.log.success(`Updated components/ui/${uiFile}`)\n updated++\n continue\n }\n\n // 3. Special: tiptap directory\n if (name === 'tiptap') {\n const srcDir = path.join(cliRoot, 'templates', 'tiptap')\n const destDir = path.join(cms, 'components', 'ui', 'tiptap')\n if (fs.existsSync(srcDir)) {\n fsExtra.copySync(srcDir, destDir, { overwrite: true })\n clack.log.success('Updated components/ui/tiptap/ (all files)')\n updated++\n } else {\n clack.log.warning('tiptap templates not found')\n skipped++\n }\n continue\n }\n\n clack.log.warning(`Unknown component: ${name}`)\n skipped++\n }\n\n clack.outro(`Updated ${updated} component${updated !== 1 ? 's' : ''}${skipped > 0 ? `, ${skipped} skipped` : ''}`)\n })\n","/**\n * update-deps command — (re-)install all required CMS dependencies.\n * Safe to run repeatedly; the package manager will skip already-installed packages.\n */\n\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport { installDependenciesAsync } from '../init/scaffolders/dependencies.js'\nimport { detectPackageManager } from '../utils/package-manager.js'\n\nexport const updateDepsCommand = new Command('update-deps')\n .description('Install or update all CMS dependencies')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Update Dependencies')\n\n const pm = detectPackageManager(cwd)\n clack.log.info(`Package manager: ${pm}`)\n\n const config = await resolveConfig(cwd)\n const includeEmail = config.features?.email ?? true\n\n const s = clack.spinner()\n s.start('Installing dependencies...')\n\n const result = await installDependenciesAsync({\n cwd,\n pm,\n includeEmail,\n includeBiome: false\n })\n\n if (result.success) {\n s.stop(`Installed ${result.coreDeps.length} deps + ${result.devDeps.length} dev deps`)\n } else {\n s.stop('Dependency install failed')\n clack.log.error(result.error ?? 'Unknown error')\n process.exit(1)\n }\n\n clack.outro('Dependencies updated')\n })\n","/**\n * update-styles command — replace cms-globals.css with the latest version\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport * as clack from '@clack/prompts'\nimport { Command } from 'commander'\nimport { resolveConfig } from '../config/resolver.js'\nimport { readTemplate } from '../init/templates/reader.js'\n\nexport const updateStylesCommand = new Command('update-styles')\n .description('Replace cms-globals.css with the latest version from the CLI')\n .option('--cwd <path>', 'Project root path')\n .action(async (options: { cwd?: string }) => {\n const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd()\n\n clack.intro('BetterStart Update Styles')\n\n const config = await resolveConfig(cwd)\n const cmsDir = config.paths?.cms ?? './cms'\n const targetPath = path.join(cwd, cmsDir, 'cms-globals.css')\n\n if (!fs.existsSync(targetPath)) {\n clack.cancel(`cms-globals.css not found at ${path.relative(cwd, targetPath)}`)\n process.exit(1)\n }\n\n fs.writeFileSync(targetPath, readTemplate('cms-globals.css'), 'utf-8')\n\n clack.log.success(`Updated ${path.relative(cwd, targetPath)}`)\n clack.outro('Styles updated')\n })\n"],"mappings":"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","names":["Command","path","fs","path","path","fs","content","parsed","fs","path","p","path","fs","fs","path","path","fs","p","fs","path","path","fs","fs","path","path","fs","fs","path","fs","path","fs","path","path","fs","p","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","fns","fs","path","generateColumnDef","fs","path","path","fs","generateColumns","path","fs","generateColumnDef","fs","path","path","fs","fs","path","findTableEnd","path","fs","fs","path","path","fs","fs","path","base","generateFieldJSX","buildZodFields","buildDefaultValues","path","fs","buildZodFields","buildDefaultValues","generateFieldJSX","fs","path","group","generateFieldJSX","buildZodFields","buildDefaultValues","path","fs","fs","path","path","fs","fs","path","parseNavigationFile","extractTopLevelArray","parseItemsBlock","parseSingleItem","generateNavigationCode","appendItem","fs","path","generatePage","path","fs","fs","path","generatePageContent","path","fs","fs","path","path","fs","fs","path","generateTable","path","fs","generateColumns","generateTable","generatePageContent","generatePage","execFileSync","fs","path","fs","path","path","fs","execFileSync","path","result","execFileSync","spawn","fs","path","p","Command","pc","execFileSync","p","p","path","fs","path","path","path","path","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","path","path","fs","path","path","path","fs","path","path","fs","fs","path","fs","path","fs","path","Command","Command","path","password","fs","runSeed","spinner","Command","pc","path","fs","execFileSync","readTemplate","spawn","password","fs","path","Command","findTableEnd","fs","Command","path","execFileSync","fs","path","p","Command","pc","Command","path","pc","execFileSync","fs","fs","path","p","Command","pc","fs","stripJsonComments","findMainCss","path","fs","p","Command","pc","fs","path","clack","Command","path","fs","Command","path","clack","Command","Command","path","fs","path","clack","Command","Command","path","fs","Command"]}