@betterstart/cli 0.1.2 → 0.1.3

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generators/actions.ts","../src/generators/shared-utils.ts","../src/generators/cache.ts","../src/generators/columns.ts","../src/generators/create-page.ts","../src/generators/database.ts","../src/generators/edit-page.ts","../src/generators/email-template.ts","../src/generators/form.ts","../src/generators/form-admin-pages.ts","../src/generators/form-generator.ts","../src/generators/form-navigation.ts","../src/generators/hook.ts","../src/generators/navigation.ts","../src/generators/page.ts","../src/generators/page-content.ts","../src/generators/table.ts","../src/shadcn/add-component.ts","../src/shadcn/exports.ts","../src/shadcn/types.ts","../src/shadcn/registry.ts","../src/shadcn/transform.ts","../src/index.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Extract many-to-many relationship fields from schema\n */\nfunction getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n return flattenFields(fields).filter(\n (f) => f.type === 'relationship' && f.multiple === true && f.relationship\n )\n}\n\n/**\n * Get all nested relationship fields (recursively checks nested fields including lists)\n */\nfunction _getNestedRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const relationships: SchemaField[] = []\n\n function checkFields(fieldsToCheck: SchemaField[]): void {\n for (const field of fieldsToCheck) {\n // Collect relationship fields (excluding many-to-many)\n if (field.type === 'relationship' && field.relationship && !field.multiple) {\n relationships.push(field)\n }\n // Check nested fields in lists\n if (field.type === 'list' && field.fields && field.fields.length > 0) {\n checkFields(field.fields)\n }\n // Check nested fields in groups\n if (field.type === 'group' && field.fields && field.fields.length > 0) {\n checkFields(field.fields)\n }\n // Check fields in tabs\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n checkFields(tab.fields)\n }\n }\n }\n }\n }\n\n checkFields(fields)\n return relationships\n}\n\n/**\n * Generate slugify helper function\n */\nfunction generateSlugifyHelper(): string {\n return `\n/**\n * Convert text to URL-friendly slug\n * - Removes special characters\n * - Converts to lowercase\n * - Replaces spaces with dashes\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^\\\\w\\\\s-]/g, '') // Remove special chars\n .replace(/\\\\s+/g, '-') // Replace spaces with dashes\n .replace(/-+/g, '-') // Replace multiple dashes with single dash\n .replace(/^-+|-+$/g, '') // Trim dashes from start/end\n}\n`\n}\n\n/**\n * Generate field mapping with proper null handling\n */\nfunction generateFieldMapping(field: SchemaField, source: string = 'input'): string {\n if (field.type === 'list') {\n return `${source}.${field.name} || []`\n }\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 // Handle optional string/varchar/select fields - convert undefined/empty to null\n if (\n !field.required &&\n (field.type === 'string' ||\n field.type === 'varchar' ||\n field.type === 'text' ||\n field.type === 'select')\n ) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n return `${source}.${field.name}`\n}\n\n/**\n * Generate TypeScript type for a field\n * @param field - The field to generate a type for\n * @param forInputOutput - 'input' for create/update inputs (IDs as strings),\n * 'output' for main data interface (full nested objects),\n * 'nested' for fields within a relationship (IDs as strings, no nested Data types)\n * @param schemasPath - Optional path to schemas directory (required for 'output' mode with relationships)\n */\nfunction getFieldType(\n field: SchemaField,\n forInputOutput: 'input' | 'output' | 'nested' = 'output',\n schemasPath?: string\n): 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 'date':\n case 'time':\n case 'timestamp':\n case 'image':\n return 'string'\n case 'relationship':\n // For input or nested, relationships are stored as IDs (strings)\n // For output, return the full related object with inline type (to handle nested relationships correctly)\n if (forInputOutput === 'input' || forInputOutput === 'nested') {\n return 'string'\n }\n if (field.relationship && schemasPath) {\n // Generate inline type for relationship to handle nested relationships correctly\n const inlineType = generateNestedRelationshipType(field.relationship, schemasPath)\n if (inlineType) {\n return `${inlineType} | null`\n }\n }\n // Fallback to simple Data type import if no schemasPath or failed to load schema\n if (field.relationship) {\n const relationshipSingular = singularize(field.relationship)\n const relationshipPascal = toPascalCase(relationshipSingular)\n return `${relationshipPascal}Data | null`\n }\n return 'string'\n case 'group':\n // Groups are stored as nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .map((f) => {\n const type = getFieldType(f, forInputOutput, schemasPath)\n return `${quotePropertyName(f.name)}?: ${type}`\n })\n .join('; ')\n return `{ ${nestedType} }`\n }\n return 'Record<string, unknown>'\n case 'list':\n // If list has nested fields, return array of objects\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .flatMap((f) => {\n // For input types, relationships are stored as IDs (strings) in JSONB\n // For output types, relationships should be full objects\n const mode = forInputOutput === 'input' ? 'input' : 'output'\n const type = getFieldType(f, mode, schemasPath)\n const fields = [`${quotePropertyName(f.name)}?: ${type}`]\n // Add icon field if hasIcon is true\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 // Curriculum stores both items and weeks - mode determines which editor to show\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 * Generate an inline type for a nested relationship field\n * Includes commonly needed fields from the related schema\n */\nfunction generateNestedRelationshipType(\n relationshipName: string,\n schemasPath: string\n): string | null {\n const relSchemaPath = path.join(schemasPath, `${relationshipName}.json`)\n if (!fs.existsSync(relSchemaPath)) {\n return null\n }\n\n try {\n const relSchemaContent = fs.readFileSync(relSchemaPath, 'utf-8')\n const relSchema = JSON.parse(relSchemaContent) as Schema\n const relDbFields = flattenFields(relSchema.fields).filter(\n (f) => !f.primaryKey && f.type !== 'tabs' && f.type !== 'group' && f.type !== 'separator'\n )\n\n const fieldTypes: string[] = ['id: number | null']\n\n // Include all database fields from the related schema\n for (const field of relDbFields) {\n const type = getFieldType(field, 'nested')\n const nullSuffix = field.required ? '' : ' | null'\n fieldTypes.push(`${quotePropertyName(field.name)}: ${type}${nullSuffix}`)\n }\n\n // Always include auto-generated database fields (they exist on every table but aren't in schema.fields)\n if (!relDbFields.some((f) => f.name === 'createdAt')) fieldTypes.push('createdAt: string')\n if (!relDbFields.some((f) => f.name === 'updatedAt')) fieldTypes.push('updatedAt: string')\n if (!relDbFields.some((f) => f.name === 'sortOrder')) fieldTypes.push('sortOrder: number')\n\n return `{ ${fieldTypes.join('; ')} }`\n } catch {\n return null\n }\n}\n\n/**\n * Generate dummy data value for a field\n */\nfunction _generateDummyValue(field: SchemaField, index: number): string {\n switch (field.type) {\n case 'serial':\n return `${index + 1}`\n case 'number':\n case 'decimal':\n if (field.name.toLowerCase().includes('price')) {\n return `${(index + 1) * 10}.99`\n }\n return `${index + 1}`\n case 'boolean':\n return index % 2 === 0 ? 'true' : 'false'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n if (field.name.toLowerCase().includes('email')) {\n return `'user${index + 1}@example.com'`\n }\n if (field.name.toLowerCase().includes('name')) {\n return `'${field.label || field.name} ${index + 1}'`\n }\n if (field.name.toLowerCase().includes('description')) {\n return `'Description for item ${index + 1}'`\n }\n return `'Sample ${field.name} ${index + 1}'`\n case 'timestamp':\n case 'date':\n return `new Date('2025-01-${String(index + 1).padStart(2, '0')}').toISOString()`\n case 'time':\n return `'${String(9 + index).padStart(2, '0')}:00:00'`\n case 'list':\n // If list has nested fields, generate array of objects\n if (field.fields && field.fields.length > 0) {\n const nestedObject = field.fields\n .map((f) => {\n const value = _generateDummyValue(f, 0)\n return `${f.name}: ${value}`\n })\n .join(', ')\n return `[{ ${nestedObject} }, { ${nestedObject.replace(/1/g, '2')} }]`\n }\n return `['Item 1', 'Item 2', 'Item 3']`\n case 'image':\n return `'https://via.placeholder.com/150'`\n default:\n return `'Value ${index + 1}'`\n }\n}\n\n/**\n * Generate server actions file in packages/lib/src/actions/\n */\nexport async function generateActions(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const actionsDir = path.join(paths.lib, 'src/actions')\n ensureDir(actionsDir)\n\n const actionsFilePath = path.join(actionsDir, `${schema.name}.ts`)\n\n // Check if file exists\n if (fs.existsSync(actionsFilePath) && !options.force) {\n console.warn(` ⚠️ Actions file already exists: ${schema.name}.ts. Use --force to overwrite.`)\n return `packages/lib/src/actions/${schema.name}.ts`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const tableVariableName = toCamelCase(schema.name)\n\n // Flatten fields to handle groups\n const dbFields = flattenFields(schema.fields)\n\n // Collect many-to-many relationship fields\n const m2mFields = getManyToManyFields(schema.fields)\n const hasM2MRelationships = m2mFields.length > 0\n\n // Collect single-value relationship fields (exclude many-to-many)\n const relationshipFields = dbFields.filter(\n (f) => f.type === 'relationship' && f.relationship && !f.multiple\n )\n\n // Filter out M2M fields from dbFields for regular processing\n const regularDbFields = dbFields.filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n // Check if schema has a slug field\n const hasSlugField = regularDbFields.some((f) => f.name === 'slug')\n\n // Check for draft mode - automatically add published field if not present\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = regularDbFields.some((f) => f.name === 'published')\n\n // Add published field for draft mode if not already present\n const allDbFields =\n hasDraftMode && !hasPublishedField\n ? [...regularDbFields, { name: 'published', type: 'boolean' as const, required: true }]\n : [...regularDbFields]\n\n // Automatically add createdAt and updatedAt if not present\n const hasCreatedAt = regularDbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = regularDbFields.some((f) => f.name === 'updatedAt')\n if (!hasCreatedAt) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!hasUpdatedAt) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n\n // Add sortOrder field for row reordering\n const hasSortOrder = regularDbFields.some((f) => f.name === 'sortOrder')\n if (!hasSortOrder) {\n allDbFields.push({ name: 'sortOrder', type: 'number' as const, required: true })\n }\n\n // Generate M2M field types for interfaces (as arrays of IDs)\n const m2mFieldTypes = m2mFields.map((f) => ` ${quotePropertyName(f.name)}: number[]`).join('\\n')\n\n // Generate optional HTML fields for markdown fields (for pre-rendered HTML content)\n const markdownHtmlFields = allDbFields\n .filter((f) => f.type === 'markdown')\n .map((f) => ` ${quotePropertyName(`${f.name}Html`)}?: string`)\n .join('\\n')\n\n // Generate TypeScript interfaces\n // Pass paths.schemas so relationship fields can generate proper inline types with nested relationships as strings\n const dataInterface = `export interface ${pascalSingular}Data {\n${allDbFields.map((f) => ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output', paths.schemas)}${f.required ? '' : ' | null'}`).join('\\n')}${markdownHtmlFields ? `\\n${markdownHtmlFields}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\n}`\n\n const responseInterface = `export interface ${pascalPlural}Response {\n ${toCamelCase(pluralName)}: ${pascalSingular}Data[]\n total: number\n}`\n\n // Generate filter interface with search and filterable fields\n // Use allDbFields to include auto-added fields like published (for draft mode)\n const filterableFields = allDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'sortOrder' &&\n ['string', 'varchar', 'text', 'boolean', 'number', 'decimal'].includes(f.type)\n )\n const filtersInterface = `export interface Get${pascalPlural}Filters {\n search?: string\n${filterableFields.map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f)}`).join('\\n')}\n limit?: number\n}`\n\n // Generate CreateInput interface (exclude auto-generated fields, but include published when draft mode)\n // Use regularDbFields to exclude M2M relationship fields (they're handled via junction tables)\n const createFields = regularDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'sortOrder' // sortOrder is auto-calculated on insert\n // Note: published is included when draft mode is enabled so users can choose to publish on create\n )\n const createInterface = `export interface Create${pascalSingular}Input {\n${createFields.map((f) => ` ${quotePropertyName(f.name)}${f.required ? '' : '?'}: ${getFieldType(f, 'input')}`).join('\\n')}${\n hasDraftMode ? `\\n published?: boolean` : ''\n}\n}`\n\n const createResultInterface = `export interface Create${pascalSingular}Result {\n success: boolean\n error?: string\n ${toCamelCase(singularName)}?: ${pascalSingular}Data\n}`\n\n // Generate UpdateInput interface\n const updateInterface = `export interface Update${pascalSingular}Input {\n id: number\n${createFields.map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`).join('\\n')}${\n hasDraftMode ? `\\n published?: boolean` : ''\n}\n}`\n\n const updateResultInterface = `export interface Update${pascalSingular}Result {\n success: boolean\n error?: string\n ${toCamelCase(singularName)}?: ${pascalSingular}Data\n}`\n\n const deleteResultInterface = `export interface Delete${pascalSingular}Result {\n success: boolean\n error?: string\n}`\n\n // Determine search fields from schema\n const searchFields = schema.search?.fields || []\n const hasSearch = searchFields.length > 0\n\n // Generate relationship joins and selects\n const hasRelationships = relationshipFields.length > 0\n const relationshipJoins = hasRelationships\n ? relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return `.leftJoin(${relTable}, sql\\`CAST(NULLIF(\\${${tableVariableName}.${f.name}}, '') AS INTEGER) = \\${${relTable}.id}\\`)`\n })\n .join('')\n : ''\n\n // Helper to load related schema and get its database fields\n // Only returns id, slug, title, name (whichever exist in the related schema)\n const getRelatedSchemaFields = (relationshipName: string): string[] => {\n const relSchemaPath = path.join(paths.schemas, `${relationshipName}.json`)\n if (fs.existsSync(relSchemaPath)) {\n try {\n const relSchemaContent = fs.readFileSync(relSchemaPath, 'utf-8')\n const relSchema = JSON.parse(relSchemaContent) as Schema\n const relDbFields = flattenFields(relSchema.fields).filter(\n (f) => !f.primaryKey && f.type !== 'tabs' && f.type !== 'group' && f.type !== 'separator'\n )\n\n // Include all database fields from the related schema\n const fieldNames = ['id']\n for (const field of relDbFields) {\n fieldNames.push(field.name)\n }\n\n // Always include auto-generated database fields (they exist on every table but aren't in schema.fields)\n if (!relDbFields.some((f) => f.name === 'createdAt')) fieldNames.push('createdAt')\n if (!relDbFields.some((f) => f.name === 'updatedAt')) fieldNames.push('updatedAt')\n if (!relDbFields.some((f) => f.name === 'sortOrder')) fieldNames.push('sortOrder')\n\n return fieldNames\n } catch {\n // Fall back to minimal fields if schema can't be loaded\n return ['id']\n }\n }\n // Fall back to minimal fields if schema doesn't exist\n return ['id']\n }\n\n const relationshipSelects = hasRelationships\n ? relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldSelects = relFields\n .map((fieldName) => ` ${fieldName}: ${relTable}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: {\n${fieldSelects}\n },`\n })\n .join('\\n')\n : ''\n\n const allFieldsSelect = allDbFields\n .filter((f) => f.type !== 'relationship')\n .map((f) => ` ${f.name}: ${tableVariableName}.${f.name},`)\n .join('\\n')\n\n const selectClause = hasRelationships\n ? `db.select({\n${allFieldsSelect}\n${relationshipSelects}\n })\n .from(${tableVariableName})${relationshipJoins}`\n : `db.select().from(${tableVariableName})`\n\n // Helper function to get relationship fields inside a list field\n const getListRelationshipFields = (field: SchemaField): SchemaField[] => {\n if (field.type !== 'list' || !field.fields) {\n return []\n }\n return field.fields.filter((f) => f.type === 'relationship' && f.relationship)\n }\n\n // Helper function to convert nested list field types\n const generateListFieldConverter = (field: SchemaField): string => {\n if (field.type !== 'list' || !field.fields || field.fields.length === 0) {\n return `row.${field.name}`\n }\n\n const hasBooleanFields = field.fields.some((f) => f.type === 'boolean')\n const hasGroupFields = field.fields.some((f) => f.type === 'group')\n const relationshipFields = getListRelationshipFields(field)\n const hasRelationships = relationshipFields.length > 0\n\n if (!hasBooleanFields && !hasRelationships && !hasGroupFields) {\n return `row.${field.name}`\n }\n\n const conversions = field.fields\n .map((f) => {\n if (f.type === 'boolean') {\n return ` ${f.name}: typeof item.${f.name} === 'string' ? item.${f.name} === 'true' : (item.${f.name} as boolean | undefined)`\n }\n if (f.type === 'relationship' && f.relationship) {\n // Relationship fields in lists are stored as string IDs\n // They will be populated by a helper function after the query\n return ` ${f.name}: item.${f.name} as string | undefined`\n }\n if (f.type === 'group' && f.fields && f.fields.length > 0) {\n // Group fields are nested objects - cast to the correct type\n const groupType = f.fields\n .map(\n (gf) =>\n `${gf.name}?: ${gf.type === 'boolean' ? 'boolean' : gf.type === 'number' || gf.type === 'decimal' ? 'number' : 'string'}`\n )\n .join('; ')\n return ` ${f.name}: item.${f.name} as { ${groupType} } | undefined`\n }\n if (f.type === 'list') {\n // For nested lists, always map to ensure all schema fields are present\n // This handles cases where old data doesn't have all fields\n if (f.fields && f.fields.length > 0) {\n // Generate conversions for ALL fields in the nested list\n const allFieldConversions = f.fields\n .map((nf) => {\n if (nf.type === 'boolean') {\n const defaultVal = nf.default === true ? 'true' : 'false'\n return ` ${nf.name}: (typeof nestedItem.${nf.name} === 'string' ? nestedItem.${nf.name} === 'true' : (nestedItem.${nf.name} as boolean | null | undefined)) ?? ${defaultVal}`\n }\n // String-like fields: use stored value or undefined\n return ` ${nf.name}: (nestedItem.${nf.name} as string | null | undefined) ?? undefined`\n })\n .join(',\\n')\n\n return ` ${f.name}: (item.${f.name} as Array<Record<string, unknown>> | undefined)?.map((nestedItem) => ({\\n${allFieldConversions}\\n }))`\n }\n\n const nestedType =\n f.fields && f.fields.length > 0\n ? `Array<{ ${f.fields.map((nf) => `${nf.name}?: ${nf.type === 'boolean' ? 'boolean' : 'string'}`).join('; ')} }>`\n : 'Array<{ name?: string }>'\n return ` ${f.name}: item.${f.name} as ${nestedType} | undefined`\n }\n return ` ${f.name}: item.${f.name} as string | undefined`\n })\n .join(',\\n')\n\n return `row.${field.name}?.map((item: Record<string, unknown>) => ({\\n${conversions}\\n })) ?? row.${field.name}`\n }\n\n // Recursive function to find all list fields with relationships, including nested ones\n const findListFieldsWithRelationships = (\n fields: SchemaField[],\n parentPath: string[] = []\n ): Array<{ field: SchemaField; path: string[] }> => {\n const result: Array<{ field: SchemaField; path: string[] }> = []\n\n for (const field of fields) {\n if (field.type === 'list' && field.fields) {\n const currentPath = [...parentPath, field.name]\n const hasRelationships = field.fields.some(\n (nestedField) => nestedField.type === 'relationship' && nestedField.relationship\n )\n\n if (hasRelationships) {\n result.push({ field, path: currentPath })\n }\n\n // Recursively check nested lists\n const nestedLists = findListFieldsWithRelationships(field.fields, currentPath)\n result.push(...nestedLists)\n }\n }\n\n return result\n }\n\n const listFieldsWithRelationships = findListFieldsWithRelationships(allDbFields)\n\n const resultMapping = hasRelationships\n ? `\n\n const mapped${pascalPlural} = results.map((row) => ({\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship') {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}\n }))\n${\n listFieldsWithRelationships.length > 0\n ? `\n // Populate relationship fields in lists\n const populated${pascalPlural} = await Promise.all(\n mapped${pascalPlural}.map(record => populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data))\n )\n\n return {\n ${toCamelCase(pluralName)}: populated${pascalPlural},\n total: populated${pascalPlural}.length\n }`\n : `\n return {\n ${toCamelCase(pluralName)}: mapped${pascalPlural},\n total: mapped${pascalPlural}.length\n }`\n}`\n : listFieldsWithRelationships.length > 0\n ? `\n\n // Populate relationship fields in lists\n const populated${pascalPlural} = await Promise.all(\n results.map(record => populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data))\n )\n\n return {\n ${toCamelCase(pluralName)}: populated${pascalPlural},\n total: populated${pascalPlural}.length\n }`\n : `\n\n return {\n ${toCamelCase(pluralName)}: results as ${pascalSingular}Data[],\n total: results.length\n }`\n\n // Generate filter-based query builder\n const filterConditions = filterableFields\n .map((f) => {\n if (f.type === 'boolean') {\n return ` // Handle exact match for ${f.name}\n if (filters?.${f.name} !== undefined) {\n conditions.push(eq(${tableVariableName}.${f.name}, filters.${f.name}))\n }`\n }\n return ` if (filters?.${f.name}) {\n conditions.push(eq(${tableVariableName}.${f.name}, filters.${f.name}))\n }`\n })\n .join('\\n')\n\n const searchQueryBuilder = hasSearch\n ? `const conditions = []\n\n // Handle search query across multiple fields\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(${tableVariableName}.${f}, searchTerm)`).join(',\\n')}\n )\n )\n }\n\n // Handle exact match filters\n${filterConditions}\n\n const query = ${selectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${tableVariableName}.sortOrder))\n : query.orderBy(asc(${tableVariableName}.sortOrder))\n\n // Apply limit if specified (useful for build-time static generation)\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery`\n : `const conditions = []\n\n // Handle exact match filters\n${filterConditions}\n\n const query = ${selectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${tableVariableName}.sortOrder))\n : query.orderBy(asc(${tableVariableName}.sortOrder))\n\n // Apply limit if specified (useful for build-time static generation)\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery`\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n const filterFields = hasFilters && schema.filters ? schema.filters.map((f) => f.field) : []\n\n // Generate individual getDistinct functions for each filter field (Drizzle doesn't support dynamic field access)\n const getDistinctFunctions =\n hasFilters && filterFields.length > 0\n ? filterFields\n .map(\n (field) => `\nexport async function getDistinct${pascalPlural}${toPascalCase(field)}(): Promise<string[]> {\n try {\n const results = await db\n .selectDistinct({ value: ${tableVariableName}.${field} })\n .from(${tableVariableName})\n .where(isNotNull(${tableVariableName}.${field}))\n .orderBy(asc(${tableVariableName}.${field}))\n \n return results.map((r) => String(r.value)).filter(Boolean)\n } catch (error) {\n console.error('Error fetching distinct ${pluralName} ${field}:', error)\n return []\n }\n}`\n )\n .join('\\n')\n : ''\n\n // Generate helper function to populate relationship fields in lists\n // Collect all relationship field info for parallel query generation\n const allRelationshipQueries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n relFieldsSelect: string\n listFieldName: string\n path: string[]\n parentField?: string\n }> = []\n\n for (const { field: listField, path } of listFieldsWithRelationships) {\n const relationshipFields = listField.fields!.filter(\n (f: SchemaField) => f.type === 'relationship' && f.relationship\n )\n\n for (const relField of relationshipFields) {\n const relTable = toCamelCase(relField.relationship!)\n const relFields = getRelatedSchemaFields(relField.relationship!)\n const relFieldsSelect = relFields.map((f) => `${f}: ${relTable}.${f}`).join(', ')\n const fieldPath = path.join('_')\n\n allRelationshipQueries.push({\n fieldPath,\n relField,\n relTable,\n relFieldsSelect,\n listFieldName: listField.name,\n path,\n parentField: path.length === 2 ? path[0] : undefined\n })\n }\n }\n\n const populateListRelationshipsFunction =\n listFieldsWithRelationships.length > 0\n ? `\n/**\n * Helper function to populate relationship fields inside list fields\n * Uses Promise.all for parallel query execution\n */\nasync function populate${pascalSingular}ListRelationships(record: ${pascalSingular}Data): Promise<${pascalSingular}Data> {\n // Phase 1: Collect all IDs (synchronous)\n${allRelationshipQueries\n .map((q) => {\n if (q.path.length === 1) {\n return ` const ${q.fieldPath}_${q.relField.name}Ids = record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})\n ? record.${q.listFieldName}\n .map((item: Record<string, unknown>) => item.${q.relField.name})\n .filter((id: unknown) => id != null && id !== '')\n .map((id: unknown) => Number.parseInt(String(id), 10))\n .filter((id: number) => !Number.isNaN(id))\n : []`\n }\n if (q.path.length === 2) {\n return ` const ${q.fieldPath}_${q.relField.name}Ids = record.${q.parentField} && Array.isArray(record.${q.parentField})\n ? record.${q.parentField}\n .flatMap((parent: Record<string, unknown>) =>\n parent.${q.listFieldName} && Array.isArray(parent.${q.listFieldName})\n ? (parent.${q.listFieldName} as Record<string, unknown>[]).map((item: Record<string, unknown>) => item.${q.relField.name})\n : []\n )\n .filter((id: unknown) => id != null && id !== '')\n .map((id: unknown) => Number.parseInt(String(id), 10))\n .filter((id: number) => !Number.isNaN(id))\n : []`\n }\n return ` // WARNING: Nested list depth ${q.path.length} not yet supported for ${q.path.join('.')}`\n })\n .join('\\n\\n')}\n\n // Phase 2: Execute all queries in parallel\n const [${allRelationshipQueries.map((q) => `${q.fieldPath}_${q.relField.name}Results`).join(', ')}] = await Promise.all([\n${allRelationshipQueries\n .map(\n (q) =>\n ` ${q.fieldPath}_${q.relField.name}Ids.length > 0\n ? db.select({ ${q.relFieldsSelect} }).from(${q.relTable}).where(inArray(${q.relTable}.id, ${q.fieldPath}_${q.relField.name}Ids))\n : Promise.resolve([])`\n )\n .join(',\\n')}\n ])\n\n // Phase 3: Build lookup maps\n${allRelationshipQueries\n .map(\n (q) =>\n ` const ${q.fieldPath}_${q.relField.name}Map = new Map(${q.fieldPath}_${q.relField.name}Results.map((rel) => [rel.id, rel]))`\n )\n .join('\\n')}\n\n // Phase 4: Map relationships back to record\n${allRelationshipQueries\n .map((q) => {\n if (q.path.length === 1) {\n return ` if (record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})) {\n record.${q.listFieldName} = record.${q.listFieldName}.map((item: Record<string, unknown>) => {\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) ? ${q.fieldPath}_${q.relField.name}Map.get(relId) || null : null\n }\n })\n }`\n }\n if (q.path.length === 2) {\n return ` if (record.${q.parentField} && Array.isArray(record.${q.parentField})) {\n record.${q.parentField} = record.${q.parentField}.map((parent: Record<string, unknown>) => {\n if (parent.${q.listFieldName} && Array.isArray(parent.${q.listFieldName})) {\n parent.${q.listFieldName} = (parent.${q.listFieldName} as Record<string, unknown>[]).map((item: Record<string, unknown>) => {\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) ? ${q.fieldPath}_${q.relField.name}Map.get(relId) || null : null\n }\n })\n }\n return parent\n })\n }`\n }\n return ''\n })\n .join('\\n\\n')}\n\n return record\n}\n`\n : ''\n\n // Pre-compute getById function body for M2M-only case (Promise.all optimization)\n const getByIdParallelBody =\n !hasRelationships && hasM2MRelationships\n ? (() => {\n const destructuring = m2mFields.map((f) => `${f.name}Result`).join(', ')\n const queries = m2mFields\n .map((f) => {\n const junctionTableVar = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `db.select({ id: ${junctionTableVar}.${relatedIdField} }).from(${junctionTableVar}).where(eq(${junctionTableVar}.${singularName}Id, id))`\n })\n .join(',\\n ')\n const idMappings = m2mFields\n .map((f) => `const ${f.name}Ids = ${f.name}Result.map(r => r.id)`)\n .join('\\n ')\n const fieldAssignments = m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')\n\n return `\n // Fetch entity and M2M relationships in parallel\n const [result, ${destructuring}] = await Promise.all([\n ${selectClause}.where(eq(${tableVariableName}.id, id)).limit(1),\n ${queries}\n ])\n\n if (result.length === 0) {\n return null\n }\n\n ${idMappings}\n\n return {\n ...result[0],\n${fieldAssignments}\n } as ${pascalSingular}Data`\n })()\n : null\n\n // Generate CRUD functions\n const getFunctions = `export async function get${pascalPlural}(filters?: Get${pascalPlural}Filters): Promise<${pascalPlural}Response> {\n try {\n ${searchQueryBuilder}${resultMapping}\n } catch (error) {\n console.error('Error fetching ${pluralName}:', error)\n return {\n ${toCamelCase(pluralName)}: [],\n total: 0\n }\n }\n}\n${getDistinctFunctions}\n\nexport async function get${pascalSingular}ById(id: number): Promise<${pascalSingular}Data | null> {\n try {${\n getByIdParallelBody !== null\n ? getByIdParallelBody\n : `\n const result = await ${selectClause}.where(eq(${tableVariableName}.id, id)).limit(1)\n\n if (result.length === 0) {\n return null\n }\n ${\n hasRelationships\n ? `\n const row = result[0]\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n `\n : ''\n }\n ${\n listFieldsWithRelationships.length > 0\n ? `const record = {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }\n\n return populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data)`\n : `return {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }`\n }`\n : `\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n \n return {\n ...result[0],\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}\n } as ${pascalSingular}Data`\n : listFieldsWithRelationships.length > 0\n ? `return populate${pascalSingular}ListRelationships(result[0] as ${pascalSingular}Data)`\n : `return result[0] as ${pascalSingular}Data`\n }`\n }`\n }\n } catch (error) {\n console.error('Error fetching ${singularName}:', error)\n return null\n }\n}${\n hasSlugField\n ? `\n\nexport async function get${pascalSingular}BySlug(slug: string): Promise<${pascalSingular}Data | null> {\n try {\n const result = await ${selectClause}.where(eq(${tableVariableName}.slug, slug)).limit(1)\n \n if (result.length === 0) {\n return null\n }\n ${\n hasRelationships\n ? `\n const row = result[0]\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, row.id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n `\n : ''\n }\n ${\n listFieldsWithRelationships.length > 0\n ? `const record = {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }\n\n return populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data)`\n : `return {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }`\n }`\n : `\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, result[0].id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n \n return {\n ...result[0],\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}\n } as ${pascalSingular}Data`\n : listFieldsWithRelationships.length > 0\n ? `return populate${pascalSingular}ListRelationships(result[0] as ${pascalSingular}Data)`\n : `return result[0] as ${pascalSingular}Data`\n }`\n }\n } catch (error) {\n console.error('Error fetching ${singularName} by slug:', error)\n return null\n }\n}`\n : ''\n }`\n\n // Generate field mappings for create function with proper null handling\n const createFieldMappings = createFields\n .map((field) => ` ${field.name}: ${generateFieldMapping(field)}`)\n .join(',\\n')\n\n const createFunction = `export async function create${pascalSingular}(input: Create${pascalSingular}Input): Promise<Create${pascalSingular}Result> {\n try {\n console.log('[Create ${pascalSingular}] Input:', input)\n ${\n schema.autoSlugify?.enabled\n ? `\n // Auto-generate slug from ${schema.autoSlugify.sourceField} if not provided\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 console.log('[Auto-slug] Generated slug:', input.${schema.autoSlugify.targetField})\n }\n `\n : ''\n }\n // Calculate next sortOrder for new item (place at end)\n const maxSortOrderResult = await db\n .select({ maxOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .orderBy(desc(${tableVariableName}.sortOrder))\n .limit(1)\n const nextSortOrder = (maxSortOrderResult[0]?.maxOrder ?? 0) + 1\n\n const result = await db.insert(${tableVariableName}).values({\n${createFieldMappings},${\n hasDraftMode\n ? `\n published: input.published ?? false,`\n : ''\n }\n sortOrder: nextSortOrder,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString()\n }).returning()\n \n console.log('[Create ${pascalSingular}] ✅ Success:', result[0])\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n ${\n hasRelationships || listFieldsWithRelationships.length > 0\n ? `\n // Fetch with relationships\n const created${pascalSingular} = await get${pascalSingular}ById(result[0].id!)\n\n return {\n success: true,\n ${toCamelCase(singularName)}: created${pascalSingular} ?? undefined\n }`\n : `\n return {\n success: true,\n ${toCamelCase(singularName)}: result[0] as ${pascalSingular}Data\n }`\n }\n } catch (error) {\n console.error('[Create ${pascalSingular}] ❌ Error:', error)\n \n let errorMessage = 'Failed to create ${singularName}'\n \n if (error instanceof Error) {\n // Parse PostgreSQL/Drizzle errors for user-friendly messages\n const pgError = error as unknown as Record<string, unknown>\n \n // Check for NOT NULL constraint violations\n if (error.message.includes('null value in column')) {\n const match = error.message.match(/null value in column \"(\\\\\\\\w+)\"/)\n if (match) {\n const fieldName = match[1]\n errorMessage = \\`Field \"$\\{fieldName}\" is required and cannot be empty\\`\n }\n }\n // Check for data type errors\n else if (error.message.includes('invalid input syntax')) {\n errorMessage = 'Invalid data format provided'\n }\n // Check for constraint violations (unique, foreign key, etc)\n else if (pgError.code === '23505') {\n errorMessage = 'A record with this value already exists'\n }\n // Check for generic empty required fields\n else if (error.message.includes('Failed query') && error.message.includes('values')) {\n errorMessage = 'Please fill in all required fields'\n }\n else {\n errorMessage = error.message\n }\n \n console.error('[Create ${pascalSingular}] Parsed error:', errorMessage)\n }\n \n // Throw error so useMutation onError is triggered\n throw new Error(errorMessage)\n }\n}`\n\n // Generate field metadata for update function\n const fieldMetadata = createFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const updateFunction = `export async function update${pascalSingular}(input: Update${pascalSingular}Input): Promise<Update${pascalSingular}Result> {\n try {\n console.log('[Update ${pascalSingular}] Input:', input)\n \n const { id, ...updateData } = input\n ${\n schema.autoSlugify?.enabled\n ? `\n // Auto-generate slug from ${schema.autoSlugify.sourceField} if:\n // 1. Slug is explicitly cleared (empty string) OR\n // 2. Slug is not provided (undefined) AND name is being updated\n if (updateData.${schema.autoSlugify.sourceField}) {\n if (\n updateData.${schema.autoSlugify.targetField} === '' ||\n updateData.${schema.autoSlugify.targetField} === undefined\n ) {\n updateData.${schema.autoSlugify.targetField} = slugify(updateData.${schema.autoSlugify.sourceField})\n console.log('[Auto-slug] Generated slug:', updateData.${schema.autoSlugify.targetField})\n }\n }\n `\n : ''\n }\n \n // Field metadata for processing\n const fieldMeta = [\n ${fieldMetadata}\n ]\n \n // Process updateData to handle optional fields\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(updateData)) {\n // Handle published field directly (boolean field, no special processing needed)\n if (key === 'published') {\n processedData[key] = value\n continue\n }\n \n const field = fieldMeta.find(f => f.name === key)\n if (!field) {\n processedData[key] = value\n continue\n }\n \n // Use helper logic: lists default to [], optional temporal/string fields convert empty to null\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (\n !field.required &&\n ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)\n ) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n \n const result = await db.update(${tableVariableName})\n .set({\n ...processedData,\n updatedAt: new Date().toISOString()\n })\n .where(eq(${tableVariableName}.id, id))\n .returning()\n \n if (result.length === 0) {\n console.error('[Update ${pascalSingular}] ❌ Not found')\n throw new Error('${pascalSingular} not found')\n }\n \n console.log('[Update ${pascalSingular}] ✅ Success:', result[0])\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n ${\n hasRelationships || listFieldsWithRelationships.length > 0\n ? `\n // Fetch with relationships\n const updated${pascalSingular} = await get${pascalSingular}ById(id)\n\n return {\n success: true,\n ${toCamelCase(singularName)}: updated${pascalSingular} ?? undefined\n }`\n : `\n return {\n success: true,\n ${toCamelCase(singularName)}: result[0] as ${pascalSingular}Data\n }`\n }\n } catch (error) {\n console.error('[Update ${pascalSingular}] ❌ Error:', error)\n \n let errorMessage = 'Failed to update ${singularName}'\n \n if (error instanceof Error) {\n // Parse PostgreSQL/Drizzle errors for user-friendly messages\n const pgError = error as unknown as Record<string, unknown>\n \n // Check for NOT NULL constraint violations\n if (error.message.includes('null value in column')) {\n const match = error.message.match(/null value in column \"(\\\\\\\\w+)\"/)\n if (match) {\n const fieldName = match[1]\n errorMessage = \\`Field \"\\${fieldName}\" is required and cannot be empty\\`\n }\n }\n // Check for data type errors\n else if (error.message.includes('invalid input syntax')) {\n errorMessage = 'Invalid data format provided'\n }\n // Check for constraint violations\n else if (pgError.code === '23505') {\n errorMessage = 'A record with this value already exists'\n }\n else {\n errorMessage = error.message\n }\n \n console.error('[Update ${pascalSingular}] Parsed error:', errorMessage)\n }\n \n // Throw error so useMutation onError is triggered\n throw new Error(errorMessage)\n }\n}`\n\n const deleteFunction = `export async function delete${pascalSingular}(id: number): Promise<Delete${pascalSingular}Result> {\n try {\n await db.delete(${tableVariableName}).where(eq(${tableVariableName}.id, id))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return {\n success: true\n }\n } catch (error) {\n console.error('Error deleting ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${singularName}'\n }\n }\n}\n\nexport async function deleteBulk${pascalPlural}(ids: number[]): Promise<Delete${pascalSingular}Result> {\n try {\n if (ids.length === 0) {\n return {\n success: false,\n error: 'No items selected for deletion'\n }\n }\n\n await db.delete(${tableVariableName}).where(inArray(${tableVariableName}.id, ids))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return {\n success: true\n }\n } catch (error) {\n console.error('Error deleting ${pluralName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${pluralName}'\n }\n }\n}\n\nexport interface Update${pascalSingular}SortOrderResult {\n success: boolean\n error?: string\n}\n\nexport async function update${pascalSingular}SortOrder(\n id: number,\n direction: 'up' | 'down'\n): Promise<Update${pascalSingular}SortOrderResult> {\n try {\n // Get current item\n const current = await db\n .select({ id: ${tableVariableName}.id, sortOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .where(eq(${tableVariableName}.id, id))\n .limit(1)\n\n if (current.length === 0) {\n return { success: false, error: '${pascalSingular} not found' }\n }\n\n const currentSortOrder = current[0].sortOrder\n\n // Find adjacent item\n const adjacent = await db\n .select({ id: ${tableVariableName}.id, sortOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .where(\n direction === 'up'\n ? lt(${tableVariableName}.sortOrder, currentSortOrder)\n : gt(${tableVariableName}.sortOrder, currentSortOrder)\n )\n .orderBy(\n direction === 'up'\n ? desc(${tableVariableName}.sortOrder)\n : asc(${tableVariableName}.sortOrder)\n )\n .limit(1)\n\n if (adjacent.length === 0) {\n // Already at the top/bottom\n return { success: true }\n }\n\n const adjacentItem = adjacent[0]\n\n // Swap sortOrder values\n await db\n .update(${tableVariableName})\n .set({ sortOrder: adjacentItem.sortOrder })\n .where(eq(${tableVariableName}.id, id))\n\n await db\n .update(${tableVariableName})\n .set({ sortOrder: currentSortOrder })\n .where(eq(${tableVariableName}.id, adjacentItem.id))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error updating sort order:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update sort order'\n }\n }\n}\n\nexport interface BulkUpdate${pascalPlural}SortOrderResult {\n success: boolean\n error?: string\n}\n\n/**\n * Bulk update sort order for multiple items at once\n */\nexport async function bulkUpdate${pascalPlural}SortOrder(\n updates: Array<{ id: number; sortOrder: number }>\n): Promise<BulkUpdate${pascalPlural}SortOrderResult> {\n try {\n if (updates.length === 0) {\n return { success: true }\n }\n\n // Update each item's sortOrder\n await Promise.all(\n updates.map((update) =>\n db\n .update(${tableVariableName})\n .set({ sortOrder: update.sortOrder })\n .where(eq(${tableVariableName}.id, update.id))\n )\n )\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error bulk updating sort order:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to bulk update sort order'\n }\n }\n}`\n\n // Generate M2M helper functions\n const m2mHelperFunctions = hasM2MRelationships\n ? m2mFields\n .map((f) => {\n const relationshipName = f.relationship || ''\n const relationshipPascal = toPascalCase(relationshipName)\n const relationshipSingular = singularize(relationshipName)\n const junctionTableName = `${singularName}${relationshipPascal}`\n const junctionTableVar = toCamelCase(junctionTableName)\n const _relTableVar = toCamelCase(relationshipName)\n const entityIdColumn = `${singularName}Id`\n const relIdColumn = `${relationshipSingular}Id`\n\n return `\n/**\n * Get ${relationshipName} for a ${singularName}\n */\nexport async function get${relationshipPascal}For${pascalSingular}(${singularName}Id: number): Promise<number[]> {\n try {\n const results = await db\n .select({ ${relIdColumn}: ${junctionTableVar}.${relIdColumn} })\n .from(${junctionTableVar})\n .where(eq(${junctionTableVar}.${entityIdColumn}, ${singularName}Id))\n \n return results.map(r => r.${relIdColumn})\n } catch (error) {\n console.error('Error fetching ${relationshipName} for ${singularName}:', error)\n return []\n }\n}\n\n/**\n * Set ${relationshipName} for a ${singularName}\n */\nexport async function set${relationshipPascal}For${pascalSingular}(\n ${singularName}Id: number,\n ${relationshipName}Ids: number[]\n): Promise<{ success: boolean; error?: string }> {\n try {\n // Delete existing relationships\n await db.delete(${junctionTableVar}).where(eq(${junctionTableVar}.${entityIdColumn}, ${singularName}Id))\n \n // Insert new relationships\n if (${relationshipName}Ids.length > 0) {\n await db.insert(${junctionTableVar}).values(\n ${relationshipName}Ids.map(${relationshipSingular}Id => ({\n ${entityIdColumn}: ${singularName}Id,\n ${relIdColumn}: ${relationshipSingular}Id\n }))\n )\n }\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error setting ${relationshipName} for ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to set ${relationshipName}'\n }\n }\n}\n\n/**\n * Add ${relationshipName} to a ${singularName}\n */\nexport async function add${relationshipPascal}To${pascalSingular}(\n ${singularName}Id: number,\n ${relationshipName}Ids: number[]\n): Promise<{ success: boolean; error?: string }> {\n try {\n // Get existing relationships\n const existing = await get${relationshipPascal}For${pascalSingular}(${singularName}Id)\n\n // Filter out already existing IDs\n const newIds = ${relationshipName}Ids.filter(id => !existing.includes(id))\n\n // Insert new relationships\n if (newIds.length > 0) {\n await db.insert(${junctionTableVar}).values(\n newIds.map(${relationshipSingular}Id => ({\n ${entityIdColumn}: ${singularName}Id,\n ${relIdColumn}: ${relationshipSingular}Id\n }))\n )\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n }\n\n return { success: true }\n } catch (error) {\n console.error('Error adding ${relationshipName} to ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to add ${relationshipName}'\n }\n }\n}`\n })\n .join('\\n')\n : ''\n\n // Generate slugify helper if auto-slugify is enabled\n const slugifyHelper = schema.autoSlugify?.enabled ? generateSlugifyHelper() : ''\n\n // Determine drizzle imports based on search and filters\n const hasFilterableFields = filterableFields.length > 0\n const needsAnd =\n (hasSearch && hasFilterableFields) || (hasFilterableFields && filterableFields.length > 1)\n const needsIlike = hasSearch\n const needsOr = hasSearch\n const needsSql = hasRelationships\n const hasFilterConfig = schema.filters && schema.filters.length > 0\n\n // Build sorted drizzle imports\n // Always include asc for sortOrder ordering, and lt/gt for updateSortOrder action\n const drizzleImportsArray = ['asc', 'desc', 'eq', 'gt', 'inArray', 'lt']\n if (needsAnd) drizzleImportsArray.push('and')\n if (needsIlike) drizzleImportsArray.push('ilike')\n if (needsOr) drizzleImportsArray.push('or')\n if (needsSql) drizzleImportsArray.push('sql')\n if (hasFilterConfig) {\n drizzleImportsArray.push('isNotNull')\n }\n const sortedDrizzleImports = [...new Set(drizzleImportsArray)].sort()\n\n // Generate relationship table imports (sorted alphabetically)\n const relationshipTableImports = hasRelationships\n ? relationshipFields\n .map((f) => toCamelCase(f.relationship!))\n .sort()\n .join(', ')\n : ''\n\n // Collect relationship tables from nested lists\n const nestedRelationshipTables = listFieldsWithRelationships\n .flatMap(({ field }) => {\n return field\n .fields!.filter((f: SchemaField) => f.type === 'relationship' && f.relationship)\n .map((f: SchemaField) => toCamelCase(f.relationship!))\n })\n .filter((table, index, self) => self.indexOf(table) === index) // unique\n .sort()\n\n // Generate junction table imports for M2M relationships\n const m2mTableImports = hasM2MRelationships\n ? m2mFields\n .map((f) => {\n const junctionTableName = `${singularName}${toPascalCase(f.relationship || '')}`\n return toCamelCase(junctionTableName)\n })\n .sort()\n : []\n\n // Generate related table imports for M2M (e.g., 'categories')\n const m2mRelatedTableImports = hasM2MRelationships\n ? m2mFields.map((f) => toCamelCase(f.relationship || '')).sort()\n : []\n\n // Build sorted database imports\n const databaseImportsArray = ['db', tableVariableName]\n if (relationshipTableImports) {\n databaseImportsArray.push(...relationshipTableImports.split(', '))\n }\n if (nestedRelationshipTables.length > 0) {\n databaseImportsArray.push(...nestedRelationshipTables)\n }\n if (hasM2MRelationships) {\n databaseImportsArray.push(...m2mTableImports, ...m2mRelatedTableImports)\n }\n const sortedDatabaseImports = [...new Set(databaseImportsArray)].sort()\n\n // Relationship type imports are no longer needed since we inline the types\n // This ensures nested relationships (e.g., bootcampLink -> instructor) are typed as strings\n // instead of requiring deeply nested Data types\n const relationshipTypeImports = ''\n\n // Type imports (no CSV/JSON import types needed)\n const typeImportsLine = ''\n\n // GitHub helper functions removed - no longer needed\n const _gitHubHelperFunctions = ''\n // Generate nested slug lookup functions (e.g., getChapterBySlug for tutorials)\n const nestedSlugLookupFunctions = schema.nestedSlugLookups?.length\n ? schema.nestedSlugLookups\n .map((lookup) => {\n const nestedName = toPascalCase(lookup.name)\n const nestedNameLower = toCamelCase(lookup.name)\n const pathParts = lookup.path.split('.')\n const slugField = lookup.slugField || 'slug'\n\n // Generate the type for the nested item based on the path\n // For \"modules.chapters\", this finds the chapter type from the modules list field\n const _generateNestedType = () => {\n // Find the nested structure from the schema fields\n // For modules.chapters:\n // - modules is a list field with chapters as a github-chapters field\n const firstPath = pathParts[0]\n const listField = flattenFields(schema.fields).find(\n (f) => f.name === firstPath && f.type === 'list'\n )\n if (!listField || !listField.fields) return 'unknown'\n\n // Look for the chapters field within the list\n if (pathParts.length > 1) {\n const chaptersField = listField.fields.find((f) => f.name === pathParts[1])\n if (chaptersField?.fields) {\n // Build type from the nested fields\n const fieldTypes = chaptersField.fields\n .map((f) => {\n const typeName =\n f.type === 'string' || f.type === 'text' || f.type === 'markdown'\n ? 'string'\n : f.type === 'number'\n ? 'number'\n : f.type === 'boolean'\n ? 'boolean'\n : 'unknown'\n return `${f.name}?: ${typeName}`\n })\n .join('; ')\n return `{ ${fieldTypes} }`\n }\n }\n return 'unknown'\n }\n\n // Generate the traversal code to find the nested item\n const generateTraversalCode = () => {\n if (pathParts.length === 2) {\n // e.g., \"modules.chapters\" - need to traverse modules array, then chapters array within each module\n const [parentArray, nestedArray] = pathParts\n return `\n // Search through ${parentArray} to find the ${nestedNameLower}\n for (const parent of ${singularName}.${parentArray} || []) {\n const items = parent.${nestedArray} as Array<{ ${slugField}?: string; [key: string]: unknown }> | undefined\n if (items) {\n const found = items.find((item) => item.${slugField} === ${nestedNameLower}Slug)\n if (found) {\n return found as ${nestedName}Data\n }\n }\n }`\n }\n // Single level path (e.g., \"chapters\")\n return `\n const items = ${singularName}.${pathParts[0]} as Array<{ ${slugField}?: string; [key: string]: unknown }> | undefined\n if (items) {\n const found = items.find((item) => item.${slugField} === ${nestedNameLower}Slug)\n if (found) {\n return found as ${nestedName}Data\n }\n }`\n }\n\n return `\n/**\n * ${nestedName} data type (nested within ${pascalSingular})\n */\nexport interface ${nestedName}Data {\n title?: string\n slug?: string\n description?: string\n content?: string\n useImage?: boolean\n image?: string\n}\n\n/**\n * Get a ${nestedNameLower} by slug from within a ${singularName}\n * Traverses the ${lookup.path} path to find the matching ${nestedNameLower}\n */\nexport async function get${nestedName}BySlug(${singularName}Slug: string, ${nestedNameLower}Slug: string): Promise<${nestedName}Data | null> {\n try {\n const ${singularName} = await get${pascalSingular}BySlug(${singularName}Slug)\n\n if (!${singularName}) {\n return null\n }\n${generateTraversalCode()}\n\n return null\n } catch (error) {\n console.error('Error fetching ${nestedNameLower} by slug:', error)\n return null\n }\n}`\n })\n .join('\\n')\n : ''\n\n // Generate cache tag for revalidation\n const cacheTagAll = `${pluralName}:all`\n\n // Combine all parts with correct import order\n const content = `'use server'\n\nimport { ${sortedDatabaseImports.join(', ')} } from '${ir.database}'\n${typeImportsLine}\nimport { ${sortedDrizzleImports.join(', ')} } from 'drizzle-orm'\nimport { updateTag } from 'next/cache'\n${relationshipTypeImports ? `${relationshipTypeImports}\\n` : ''}\n// Cache tag for immediate invalidation - ensures users see their changes instantly\nconst CACHE_TAG = '${cacheTagAll}'\n${dataInterface}\n\n${responseInterface}\n\n${filtersInterface}\n\n${createInterface}\n\n${createResultInterface}\n\n${updateInterface}\n\n${updateResultInterface}\n\n${deleteResultInterface}\n${slugifyHelper}${populateListRelationshipsFunction}\n\n${getFunctions}\n\n${createFunction}\n\n${updateFunction}\n\n${deleteFunction}${m2mHelperFunctions}${nestedSlugLookupFunctions}\n`\n\n fs.writeFileSync(actionsFilePath, content, 'utf-8')\n\n // Update index.ts to export new actions\n const indexPath = path.join(actionsDir, 'index.ts')\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n const exportLine = `export * from './${schema.name}'`\n if (!indexContent.includes(exportLine)) {\n indexContent += `\\n${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n }\n } else {\n fs.writeFileSync(indexPath, `export * from './${schema.name}'\\n`, 'utf-8')\n }\n\n // Update package.json exports to include the new actions entry\n const packageJsonPath = path.join(paths.lib, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const exportKey = `./actions/${schema.name}`\n if (packageJson.exports && !packageJson.exports[exportKey]) {\n packageJson.exports[exportKey] = {\n types: `./src/actions/${schema.name}.ts`,\n import: `./src/actions/${schema.name}.ts`\n }\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, 'utf-8')\n }\n }\n\n return `packages/lib/src/actions/${schema.name}.ts`\n}\n","import type { SchemaField } from '../types'\n\n/**\n * Auto-generated ID field that's injected if not present in schema\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 hasIdField = fields.some((f) => f.primaryKey || f.name === 'id')\n if (hasIdField) {\n return fields\n }\n // Prepend the auto-generated ID field\n return [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 // First ensure we have an ID field\n const fieldsWithId = ensureIdField(fields)\n const flattened: SchemaField[] = []\n\n for (const field of fieldsWithId) {\n if (field.type === 'group' && field.fields) {\n // Recursively flatten nested fields in groups (without adding ID again)\n flattened.push(...flattenFieldsWithoutIdCheck(field.fields))\n } else if (field.type === 'tabs' && field.tabs) {\n // Flatten all fields from all tabs (recursively to handle groups inside tabs)\n for (const tab of field.tabs) {\n if (tab.fields) {\n // Don't ensure ID again for nested fields (they're not top-level)\n flattened.push(...flattenFieldsWithoutIdCheck(tab.fields))\n }\n }\n } else {\n flattened.push(field)\n }\n }\n\n return flattened\n}\n\n/**\n * Internal helper to flatten without adding ID (for nested structures)\n */\nfunction flattenFieldsWithoutIdCheck(fields: SchemaField[]): SchemaField[] {\n const flattened: SchemaField[] = []\n\n for (const field of fields) {\n if (field.type === 'group' && 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","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getPaths,\n pluralize,\n singularize,\n toCamelCase,\n toPascalCase,\n toScreamingSnakeCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\ninterface NestedLookupConfig {\n name: string // e.g., 'chapter'\n pascalName: string // e.g., 'Chapter'\n camelName: string // e.g., 'chapter'\n screamingSnake: string // e.g., 'CHAPTER'\n path: string // e.g., 'modules.chapters'\n slugField: string // e.g., 'slug'\n}\n\ninterface CacheConfig {\n name: string // Schema name (e.g., 'posts')\n singularName: string // e.g., 'post'\n pluralName: string // e.g., 'posts'\n pascalSingular: string // e.g., 'Post'\n pascalPlural: string // e.g., 'Posts'\n screamingSnake: string // e.g., 'POSTS'\n hasSlug: boolean\n hasFilters: boolean\n filters: Array<{ field: string; label: string; type?: string }>\n nestedLookups: NestedLookupConfig[] // Nested slug lookup configs\n}\n\n/**\n * Load all schemas from the schemas directory\n */\nfunction loadAllSchemas(): Schema[] {\n const paths = getPaths()\n const schemasDir = paths.schemas\n\n if (!fs.existsSync(schemasDir)) {\n return []\n }\n\n const schemaFiles = fs\n .readdirSync(schemasDir)\n .filter((f) => f.endsWith('.json') && f !== 'schema.json')\n\n const schemas = schemaFiles.map((file) => {\n const content = fs.readFileSync(path.join(schemasDir, file), 'utf-8')\n return JSON.parse(content) as Schema\n })\n\n // Deduplicate by schema name (last one wins if multiple files share the same name)\n const seen = new Map<string, Schema>()\n for (const schema of schemas) {\n seen.set(schema.name, schema)\n }\n return Array.from(seen.values())\n}\n\n/**\n * Build cache config from a schema\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 // Build nested lookup configs\n const nestedLookups: NestedLookupConfig[] = (schema.nestedSlugLookups || []).map((lookup) => ({\n name: lookup.name,\n pascalName: toPascalCase(lookup.name),\n camelName: toCamelCase(lookup.name),\n screamingSnake: toScreamingSnakeCase(lookup.name),\n path: lookup.path,\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: toScreamingSnakeCase(pluralName),\n hasSlug,\n hasFilters: !!(schema.filters && schema.filters.length > 0),\n filters: schema.filters || [],\n nestedLookups\n }\n}\n\n/**\n * Generate cache/tags.ts - Cache tag constants\n */\nfunction generateTagsContent(configs: CacheConfig[]): string {\n const tagEntries: string[] = []\n\n for (const config of configs) {\n const { screamingSnake, pluralName, singularName, hasSlug, nestedLookups } = config\n\n // Add ALL tag\n tagEntries.push(` ${screamingSnake}_ALL: '${pluralName}:all'`)\n\n // Add BY_SLUG tag if schema has slug field\n if (hasSlug) {\n tagEntries.push(\n ` ${screamingSnake}_BY_SLUG: (slug: string) => \\`${pluralName}:slug:\\${slug}\\``\n )\n }\n\n // Add nested lookup tags\n for (const nested of nestedLookups) {\n tagEntries.push(\n ` ${screamingSnake}_${nested.screamingSnake}_BY_SLUG: (${singularName}Slug: string, ${nested.camelName}Slug: string) => \\`${pluralName}:\\${${singularName}Slug}:${nested.name}:\\${${nested.camelName}Slug}\\``\n )\n }\n }\n\n // Sort alphabetically for consistency\n tagEntries.sort()\n\n return `/**\n * Cache tag constants for Next.js 'use cache' invalidation\n * Tags follow the pattern: entity:scope\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nexport const CACHE_TAGS = {\n${tagEntries.join(',\\n')}\n} as const\n`\n}\n\n/**\n * Generate cache/cached-queries.ts - Cached wrapper functions\n */\nfunction generateCachedQueriesContent(configs: CacheConfig[]): string {\n const imports: string[] = []\n const typeImports: string[] = []\n const functions: string[] = []\n\n for (const config of configs) {\n const { pascalSingular, pascalPlural, screamingSnake, singularName, hasSlug, nestedLookups } =\n config\n\n // Add action imports\n imports.push(`get${pascalPlural}`)\n if (hasSlug) {\n imports.push(`get${pascalSingular}BySlug`)\n }\n\n // Add nested lookup action imports\n for (const nested of nestedLookups) {\n imports.push(`get${nested.pascalName}BySlug`)\n }\n\n // All generated actions have a filters parameter, so always add the type import\n typeImports.push(`Get${pascalPlural}Filters`)\n\n // Generate getCached[Plural] function - always with filters support\n functions.push(`\nexport const getCached${pascalPlural} = async (filters?: Get${pascalPlural}Filters) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${pascalPlural}(filters)\n}`)\n\n // Generate getCached[Singular]BySlug function if has slug\n if (hasSlug) {\n functions.push(`\nexport const getCached${pascalSingular}BySlug = async (slug: string) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_BY_SLUG(slug))\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${pascalSingular}BySlug(slug)\n}`)\n }\n\n // Generate getCached[NestedName]BySlug functions\n for (const nested of nestedLookups) {\n functions.push(`\nexport const getCached${nested.pascalName}BySlug = async (${singularName}Slug: string, ${nested.camelName}Slug: string) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_${nested.screamingSnake}_BY_SLUG(${singularName}Slug, ${nested.camelName}Slug))\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${nested.pascalName}BySlug(${singularName}Slug, ${nested.camelName}Slug)\n}`)\n }\n }\n\n // Sort imports alphabetically\n imports.sort()\n typeImports.sort()\n\n const typeImportsStr =\n typeImports.length > 0\n ? `\\nimport type {\\n ${typeImports.join(',\\n ')}\\n} from '../actions'`\n : ''\n\n return `'use cache'\n\n/**\n * Cached query functions for Next.js 'use cache'\n * Wrap existing actions with cache tags for automatic invalidation\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nimport { cacheLife, cacheTag } from 'next/cache'${typeImportsStr}\nimport {\n ${imports.join(',\\n ')}\n} from '../actions'\nimport { CACHE_TAGS } from './tags'\n${functions.join('\\n')}\n`\n}\n\n/**\n * Generate cache/revalidate.ts - Revalidation helpers\n */\nfunction generateRevalidateContent(configs: CacheConfig[]): string {\n const functions: string[] = []\n\n for (const config of configs) {\n const { pascalSingular, pascalPlural, screamingSnake, singularName, hasSlug, nestedLookups } =\n config\n\n // Generate revalidate[Plural] function\n functions.push(`\nexport const revalidate${pascalPlural} = async () => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n\n // Generate revalidate[Singular]BySlug function if has slug\n if (hasSlug) {\n functions.push(`\nexport const revalidate${pascalSingular}BySlug = async (slug: string) => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_BY_SLUG(slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n\n // Generate revalidate[NestedName]BySlug functions\n for (const nested of nestedLookups) {\n functions.push(`\nexport const revalidate${nested.pascalName}BySlug = async (${singularName}Slug: string, ${nested.camelName}Slug: string) => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_${nested.screamingSnake}_BY_SLUG(${singularName}Slug, ${nested.camelName}Slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n }\n\n return `'use server'\n\n/**\n * Revalidation helpers for Next.js cache invalidation\n * Call these functions after mutations to invalidate relevant caches\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAGS } from './tags'\n\n// Use 'max' strategy for stale-while-revalidate behavior\nconst REVALIDATION_STRATEGY = 'max' as const\n${functions.join('\\n')}\n`\n}\n\n/**\n * Generate index.ts for the cache module\n */\nfunction generateCacheIndexContent(): string {\n return `/**\n * Cache module exports\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nexport * from './tags'\nexport * from './cached-queries'\nexport * from './cached-queries-custom'\nexport * from './revalidate'\n`\n}\n\n/**\n * Generate all cache files based on all schemas\n */\nexport async function generateCache(\n _schema: Schema,\n _options: GeneratorOptions\n): Promise<string[]> {\n const paths = getPaths()\n const cacheDir = path.join(paths.lib, 'src', 'cache')\n ensureDir(cacheDir)\n\n // Load all schemas\n const schemas = loadAllSchemas()\n\n // Build cache configs for all schemas\n const configs = schemas.map(buildCacheConfig)\n\n // Sort configs by name for consistent output\n configs.sort((a, b) => a.name.localeCompare(b.name))\n\n const generatedFiles: string[] = []\n\n // Generate tags.ts\n const tagsContent = generateTagsContent(configs)\n const tagsPath = path.join(cacheDir, 'tags.ts')\n fs.writeFileSync(tagsPath, tagsContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/tags.ts')\n\n // Generate cached-queries.ts\n const cachedQueriesContent = generateCachedQueriesContent(configs)\n const cachedQueriesPath = path.join(cacheDir, 'cached-queries.ts')\n fs.writeFileSync(cachedQueriesPath, cachedQueriesContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/cached-queries.ts')\n\n // Generate revalidate.ts\n const revalidateContent = generateRevalidateContent(configs)\n const revalidatePath = path.join(cacheDir, 'revalidate.ts')\n fs.writeFileSync(revalidatePath, revalidateContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/revalidate.ts')\n\n // Generate index.ts\n const indexContent = generateCacheIndexContent()\n const indexPath = path.join(cacheDir, 'index.ts')\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/index.ts')\n\n return generatedFiles\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaColumn, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Determine if a column should be sortable by default based on its type\n * Most column types are sortable, except for image, link, custom, and avatar\n */\nfunction isSortableColumn(column: SchemaColumn): boolean {\n // If explicitly set in schema, use that value\n if (typeof column.sortable === 'boolean') {\n return column.sortable\n }\n\n // Default sortable based on column type\n const nonSortableTypes = ['image', 'avatar', 'link', 'custom']\n return !nonSortableTypes.includes(column.type)\n}\n\n/**\n * Generate title fallback chain based on available fields\n * Checks for title, name, then id in that order\n */\nfunction generateTitleFallback(fields: SchemaField[]): string {\n const fieldNames = new Set(fields.map((f) => f.name))\n const fallbacks: string[] = []\n\n // Always include id as final fallback\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\n return fallbacks.join(' || ')\n}\n\n/**\n * Generate column definition based on type\n */\nfunction generateColumnDef(column: SchemaColumn, availableFields: SchemaField[]): string {\n // Handle sortable header\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 // Generate cell renderer based on column type\n let cellDef = ''\n\n const titleFallback = generateTitleFallback(availableFields)\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\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\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\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${column.accessorKey}') as string\n return (\n <div className=\"text-sm font-medium\">{email}</div>\n )\n }`\n break\n\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', {\n style: 'currency',\n currency: 'USD'\n }).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\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\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\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\">—</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 {truncate(value, 50)}\n </a>\n )\n }`\n break\n\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\n/**\n * Generate first column definition with integrated checkbox\n */\nfunction generateColumnDefWithCheckbox(\n column: SchemaColumn,\n availableFields: SchemaField[],\n schemaName: string\n): string {\n // Handle sortable header with checkbox\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 // Generate cell renderer with checkbox based on column type\n let cellDef = ''\n const titleFallback = generateTitleFallback(availableFields)\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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 {truncate(value, 50)}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">—</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\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={\\`/admin/${schemaName}/\\${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/**\n * Generate columns file\n */\nexport async function generateColumns(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const columnsFilePath = path.join(adminDir, 'columns.tsx')\n\n // Check if file exists\n if (fs.existsSync(columnsFilePath) && !options.force) {\n console.warn(` ⚠️ Columns file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/columns.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n // Check what components we need\n let needsArrowUpDown = false\n let needsTrash = false\n let needsBadge = false\n let needsButton = false\n let needsLink = false\n let needsReactQueryClient = false\n let needsToast = false\n let needsAvatar = false\n let needsAlertDialog = false\n let needsTruncate = false\n const needsCheckbox = true // Always need checkbox for row selection\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') {\n needsBadge = true\n }\n if (column.type === 'image' || column.type === 'avatar') {\n needsAvatar = true\n }\n if (column.type === 'link') {\n needsTruncate = true\n }\n }\n\n // Check actions configuration\n const hasEdit = schema.actions?.edit ?? false\n const hasDelete = schema.actions?.delete ?? false\n\n // Always include actions column\n needsButton = true\n if (hasDelete) {\n needsTrash = true\n needsAlertDialog = true\n needsReactQueryClient = true\n needsToast = true\n }\n\n // Get flattened fields for title fallback generation\n const flattenedFields = flattenFields(schema.fields || [])\n const titleFallback = generateTitleFallback(flattenedFields)\n\n // Build imports\n const lucideIcons: string[] = []\n if (needsArrowUpDown) lucideIcons.push('ArrowUpDown')\n // Always include ChevronUp and ChevronDown for reorder buttons\n lucideIcons.push('ChevronDown', 'ChevronUp')\n // Always include Edit icon for first column hover effect\n lucideIcons.push('Edit')\n if (needsTrash) lucideIcons.push('Trash')\n\n const uiComponents: string[] = []\n if (needsButton) uiComponents.push('Button')\n if (needsBadge) uiComponents.push('Badge')\n if (needsCheckbox) uiComponents.push('Checkbox')\n if (needsAvatar) uiComponents.push('Avatar', 'AvatarImage', 'AvatarFallback')\n if (needsAlertDialog) {\n uiComponents.push(\n 'AlertDialog',\n 'AlertDialogAction',\n 'AlertDialogCancel',\n 'AlertDialogContent',\n 'AlertDialogDescription',\n 'AlertDialogFooter',\n 'AlertDialogHeader',\n 'AlertDialogTitle',\n 'AlertDialogTrigger'\n )\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 // Create placeholder custom cell component\n await createCustomCellComponent(schema, column.component, options)\n }\n }\n\n // All columns from schema\n const allColumns = [...schema.columns]\n\n // Modify first column to include checkbox\n const firstColumn = allColumns[0]\n const restColumns = allColumns.slice(1)\n\n // Generate first column with checkbox - always needs Link for navigation\n needsLink = true\n const firstColumnWithCheckbox = generateColumnDefWithCheckbox(\n firstColumn,\n flattenedFields,\n schema.name\n )\n const restColumnDefs = restColumns\n .map((col) => generateColumnDef(col, flattenedFields))\n .join(',\\n')\n\n // Add actions column\n let editButton = ''\n if (hasEdit) {\n editButton = ` <Button variant=\"outline\" className=\"size-8\" asChild>\n <Link href={\\`/admin/${schema.name}/\\${row.original.id}/edit\\`}>\n <Edit className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Edit ${singularName} {${titleFallback}}</span>\n </Link>\n </Button>`\n }\n\n // Add delete handler if delete action is enabled\n let deleteHandler = ''\n\n if (hasDelete) {\n deleteHandler = `\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${pascalSingular}(id)\n \n if (result.success) {\n toast.success('${pascalSingular} deleted successfully')\n // Refetch the list\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${singularName}')\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 ${singularName} \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete ${singularName}</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 ${singularName}.\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 // Reorder handler for move up/down buttons (client-side only when reorder mode is enabled)\n const reorderHandler = `\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 // Reorder column at the beginning (only shown when reorderMode is enabled)\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 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 // Build lib imports\n const libImports: string[] = []\n if (hasDelete) libImports.push(`delete${pascalSingular}`)\n\n const content = `'use client'\n\nimport type { ColumnDef } from '@tanstack/react-table'\n${needsReactQueryClient ? \"import { useQueryClient } from '@tanstack/react-query'\" : ''}\n${lucideIcons.length > 0 ? `import { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\n${needsLink ? \"import Link from 'next/link'\" : ''}\nimport * as React from 'react'\n${needsToast ? \"import { toast } from 'sonner'\" : ''}\n${uiComponents.length > 0 ? `import {\\n ${uiComponents.join(',\\n ')}\\n} from '${ir.adminUi}'` : ''}\n${libImports.length > 0 ? `import { ${libImports.join(', ')} } from '${ir.actions(schema.name)}'` : ''}\nimport type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n${needsTruncate ? `import { truncate } from '${ir.utils}'` : ''}\n${customImports.join('\\n')}\n${deleteHandler}${reorderHandler}\nexport const columns: ColumnDef<${pascalSingular}Data>[] = [\n${reorderColumn},\n${firstColumnWithCheckbox}${restColumnDefs ? `,\\n${restColumnDefs}` : ''},\n${actionsColumn}\n]\n`\n\n fs.writeFileSync(columnsFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/columns.tsx`\n}\n\n/**\n * Create placeholder custom cell component\n */\nasync function createCustomCellComponent(\n schema: Schema,\n componentName: string,\n options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const ir = getImportResolver()\n const cellsDir = path.join(paths.app, 'app/(admin)/admin', schema.name, 'cells')\n ensureDir(cellsDir)\n\n const componentFilePath = path.join(cellsDir, `${componentName}.tsx`)\n\n // Check if file exists\n if (fs.existsSync(componentFilePath) && !options.force) {\n return\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n const content = `import type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n\ninterface ${componentName}Props {\n data: ${pascalSingular}Data\n}\n\nexport function ${componentName}({ data }: ${componentName}Props) {\n // TODO: Implement custom cell rendering\n return (\n <div>\n {/* Add your custom rendering logic here */}\n {JSON.stringify(data)}\n </div>\n )\n}\n`\n\n fs.writeFileSync(componentFilePath, content, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n singularize,\n singularizeLabel,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate create page component\n */\nexport async function generateCreatePage(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string> {\n const paths = getPaths()\n const newDir = path.join(paths.app, 'app/(admin)/admin', schema.name, 'new')\n ensureDir(newDir)\n\n const pageFilePath = path.join(newDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Create page already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/new/page.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n const ir = getImportResolver()\n\n const content = `import { ArrowLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { connection } from 'next/server'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\nimport { Button } from '${ir.adminUi}'\nimport { ${pascalSingular}Form } from '../${schema.name}-form'\n\nexport default async function Page() {\n await connection()\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader\n title=\"Create ${singularizeLabel(schema.label)}\"\n description=\"Add a new ${singularizeLabel(schema.label).toLowerCase()} to the system\"\n />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/${schema.name}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${schema.label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-6\">\n <${pascalSingular}Form key={Date.now()} />\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/new/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getMigrationTimestamp,\n getPaths,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Extract many-to-many relationship fields from schema\n */\nfunction getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n return flattenFields(fields).filter(\n (f) => f.type === 'relationship' && f.multiple === true && f.relationship\n )\n}\n\n/**\n * Check if field name suggests it's a URL field\n */\nfunction isUrlField(fieldName: string): boolean {\n const urlKeywords = [\n 'url',\n 'website',\n 'link',\n 'href',\n 'src',\n 'image',\n 'banner',\n 'logo',\n 'video',\n 'media'\n ]\n const lowerName = fieldName.toLowerCase()\n return urlKeywords.some((keyword) => lowerName.includes(keyword))\n}\n\n/**\n * Map field type to Drizzle type and track required import\n */\nfunction getDrizzleType(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 // Use text() for URL-like fields or if no length specified and field name suggests URL\n if (isUrlField(field.name) && !field.length) {\n requiredImports.add('text')\n return 'text()'\n }\n requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'image':\n // Image fields (URLs) should use text() to handle long URLs\n requiredImports.add('text')\n return 'text()'\n case 'text':\n case 'markdown':\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: 10, scale: 2 })'\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 requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'select':\n requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'list':\n requiredImports.add('jsonb')\n // If list has nested fields, store as array of objects, otherwise as array of strings\n if (field.fields && field.fields.length > 0) {\n // Generate type for nested object, handling nested lists and groups recursively\n const nestedType = field.fields\n .flatMap((f) => {\n let type: string\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n // Nested list with fields - array of objects\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 === 'group' && f.fields && f.fields.length > 0) {\n // Nested group - object with sub-fields\n const innerType = f.fields\n .map((gf) => {\n let gfType: string\n if (gf.type === 'boolean') {\n gfType = 'boolean'\n } else if (gf.type === 'number' || gf.type === 'decimal') {\n gfType = 'number'\n } else {\n gfType = 'string'\n }\n return `${quotePropertyName(gf.name)}?: ${gfType}`\n })\n .join('; ')\n type = `{ ${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 fields = [`${quotePropertyName(f.name)}?: ${type}`]\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n fields.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return fields\n })\n .join('; ')\n return `jsonb().$type<Array<{ ${nestedType} }>>()`\n }\n return 'jsonb().$type<string[]>()'\n case 'curriculum':\n requiredImports.add('jsonb')\n return `jsonb().$type<{ 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 requiredImports.add('text')\n return 'text()'\n }\n}\n\n/**\n * Get field modifiers (notNull, default, primaryKey)\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 // Skip empty string defaults for date/timestamp fields as they're invalid in PostgreSQL\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 if (typeof field.default === 'boolean') {\n modifiers.push(`.default(${field.default})`)\n } else {\n modifiers.push(`.default(${field.default})`)\n }\n }\n\n // Add default timestamps for createdAt and updatedAt\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 * Generate Drizzle schema definition\n */\nfunction generateSchemaDefinition(\n schema: Schema,\n requiredImports: Set<string>,\n needsSql: { value: boolean }\n): string {\n const tableName = toPascalCase(schema.name)\n\n // Always need pgTable\n requiredImports.add('pgTable')\n\n // Flatten fields to handle groups, excluding many-to-many relationships (handled via junction tables)\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n // Add published field automatically when draft mode is enabled\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = dbFields.some((f) => f.name === 'published')\n\n const fieldDefinitions = dbFields\n .map((field) => {\n const drizzleType = getDrizzleType(field, requiredImports)\n const modifiers = getFieldModifiers(field, needsSql)\n return ` ${field.name}: ${drizzleType}${modifiers}`\n })\n .join(',\\n')\n\n // Add published field for draft mode if not already present\n const publishedField =\n hasDraftMode && !hasPublishedField ? `,\\n published: boolean().notNull().default(false)` : ''\n\n if (hasDraftMode && !hasPublishedField) {\n requiredImports.add('boolean')\n }\n\n // Automatically add createdAt and updatedAt if not present\n const hasCreatedAt = dbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = dbFields.some((f) => f.name === 'updatedAt')\n\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 // Add sortOrder field for row reordering (automatically added to all tables)\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n let sortOrderField = ''\n if (!hasSortOrder) {\n requiredImports.add('integer')\n sortOrderField = `,\\n sortOrder: integer().notNull().default(0)`\n }\n\n // Convert kebab-case schema names to camelCase for variable names\n const variableName = toCamelCase(schema.name)\n\n return `\nexport const ${variableName} = pgTable(\n '${tableName}',\n {\n${fieldDefinitions}${publishedField}${timestampFields}${sortOrderField}\n }\n)\n`\n}\n\n/**\n * Generate junction table definition for many-to-many relationships\n */\nfunction generateJunctionTableDefinition(\n schemaName: string,\n relationshipField: SchemaField,\n requiredImports: Set<string>\n): string {\n const singularSchema = singularize(schemaName)\n const singularRelationship = singularize(relationshipField.relationship || '')\n\n // Junction table name: e.g., postCategories\n const junctionTableName = `${singularSchema}${toPascalCase(relationshipField.relationship || '')}`\n const junctionTablePascal = toPascalCase(junctionTableName)\n\n // Column names: postId, categoryId\n const schemaIdColumn = `${singularSchema}Id`\n const relationshipIdColumn = `${singularRelationship}Id`\n\n // Table references\n const schemaTableRef = toCamelCase(schemaName)\n const relationshipTableRef = toCamelCase(relationshipField.relationship || '')\n\n requiredImports.add('pgTable')\n requiredImports.add('integer')\n requiredImports.add('primaryKey')\n\n return `\nexport const ${toCamelCase(junctionTableName)} = pgTable(\n '${junctionTablePascal}',\n {\n ${schemaIdColumn}: integer().notNull().references(() => ${schemaTableRef}.id, { onDelete: 'cascade' }),\n ${relationshipIdColumn}: integer().notNull().references(() => ${relationshipTableRef}.id, { onDelete: 'cascade' })\n },\n (table) => [primaryKey({ columns: [table.${schemaIdColumn}, table.${relationshipIdColumn}] })]\n)\n`\n}\n\n/**\n * Generate SQL for junction table migration\n */\nfunction generateJunctionTableSQL(schemaName: string, relationshipField: SchemaField): string {\n const singularSchema = singularize(schemaName)\n const singularRelationship = singularize(relationshipField.relationship || '')\n\n // Junction table name: e.g., PostCategories\n const junctionTableName = `${singularSchema}${toPascalCase(relationshipField.relationship || '')}`\n const junctionTablePascal = toPascalCase(junctionTableName)\n\n // Column names\n const schemaIdColumn = `${singularSchema}Id`\n const relationshipIdColumn = `${singularRelationship}Id`\n\n // Referenced tables\n const schemaTable = toPascalCase(schemaName)\n const relationshipTable = toPascalCase(relationshipField.relationship || '')\n\n return `-- CreateJunctionTable\nCREATE TABLE \"${junctionTablePascal}\" (\n \"${schemaIdColumn}\" INTEGER NOT NULL REFERENCES \"${schemaTable}\"(\"id\") ON DELETE CASCADE,\n \"${relationshipIdColumn}\" INTEGER NOT NULL REFERENCES \"${relationshipTable}\"(\"id\") ON DELETE CASCADE,\n PRIMARY KEY (\"${schemaIdColumn}\", \"${relationshipIdColumn}\")\n);\n\n-- CreateIndex for faster lookups\nCREATE INDEX \"idx_${junctionTablePascal}_${schemaIdColumn}\" ON \"${junctionTablePascal}\" (\"${schemaIdColumn}\");\nCREATE INDEX \"idx_${junctionTablePascal}_${relationshipIdColumn}\" ON \"${junctionTablePascal}\" (\"${relationshipIdColumn}\");\n`\n}\n\n/**\n * Map field type to SQL type\n */\nfunction getSQLType(field: SchemaField): string {\n switch (field.type) {\n case 'serial':\n return 'SERIAL PRIMARY KEY'\n case 'string':\n case 'varchar':\n // Use TEXT for URL-like fields or if no length specified and field name suggests URL\n if (isUrlField(field.name) && !field.length) {\n return 'TEXT'\n }\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n case 'image':\n // Image fields (URLs) should use TEXT to handle long URLs\n return 'TEXT'\n case 'text':\n case 'markdown':\n return 'TEXT'\n case 'number':\n case 'decimal':\n if (field.precision && field.scale) {\n return `DECIMAL(${field.precision}, ${field.scale})`\n }\n return 'INTEGER'\n case 'boolean':\n return 'BOOLEAN'\n case 'timestamp':\n return 'TIMESTAMP(3)'\n case 'date':\n return 'DATE'\n case 'time':\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n case 'select':\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n default:\n return 'TEXT'\n }\n}\n\n/**\n * Generate SQL migration file\n */\nfunction generateMigrationSQL(schema: Schema): string {\n const tableName = toPascalCase(schema.name)\n\n // Flatten fields to handle groups, excluding many-to-many relationships\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n const columns = dbFields\n .filter((field) => !field.primaryKey) // Serial primary keys are handled separately\n .map((field) => {\n let def = ` \"${field.name}\" ${getSQLType(field)}`\n\n if (field.required) {\n def += ' NOT NULL'\n }\n\n // Skip empty string defaults for date/timestamp fields as they're invalid in PostgreSQL\n const isDateField = field.type === 'date' || field.type === 'timestamp'\n const hasValidDefault = field.default !== undefined && !(isDateField && field.default === '')\n\n if (hasValidDefault) {\n if (typeof field.default === 'string') {\n def += ` DEFAULT '${field.default}'`\n } else if (typeof field.default === 'boolean') {\n def += ` DEFAULT ${field.default}`\n } else {\n def += ` DEFAULT ${field.default}`\n }\n }\n\n // Add default timestamps\n if (field.name === 'createdAt' || field.name === 'updatedAt') {\n def += ' DEFAULT CURRENT_TIMESTAMP'\n }\n\n return def\n })\n\n // Add primary key field at the beginning\n const pkField = dbFields.find((f) => f.primaryKey)\n const pkColumn = pkField\n ? ` \"${pkField.name}\" ${getSQLType(pkField)}`\n : ' \"id\" SERIAL PRIMARY KEY'\n\n // Add sortOrder column for row reordering\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n const sortOrderColumn = !hasSortOrder ? ',\\n \"sortOrder\" INTEGER NOT NULL DEFAULT 0' : ''\n\n const allColumns = [pkColumn, ...columns].join(',\\n') + sortOrderColumn\n\n // Add index on sortOrder for efficient ordering queries\n const sortOrderIndex = !hasSortOrder\n ? `\\n\\n-- CreateIndex for sortOrder\\nCREATE INDEX \"idx_${tableName}_sortOrder\" ON \"${tableName}\" (\"sortOrder\");`\n : ''\n\n return `-- CreateTable\nCREATE TABLE \"${tableName}\" (\n${allColumns}\n);${sortOrderIndex}\n`\n}\n\n/**\n * Update imports in schema.ts file\n */\nfunction updateImports(content: string, requiredImports: Set<string>, needsSql: boolean): string {\n // Parse existing imports\n const drizzleImportMatch = content.match(\n /import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/\n )\n const sqlImportExists = content.includes(\"import { sql } from 'drizzle-orm'\")\n\n let existingImports = new Set<string>()\n if (drizzleImportMatch) {\n const imports = drizzleImportMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter((i) => i)\n existingImports = new Set(imports)\n }\n\n // Merge required imports with existing\n const allImports = new Set([...existingImports, ...requiredImports])\n const sortedImports = Array.from(allImports).sort()\n\n // Build new import statement\n const newDrizzleImport = `import {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n\n // Update content\n let updatedContent = content\n\n // Replace or add drizzle-orm/pg-core import\n if (drizzleImportMatch) {\n updatedContent = updatedContent.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n newDrizzleImport\n )\n } else {\n // Add import after sql import or at the beginning\n if (sqlImportExists) {\n updatedContent = updatedContent.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm['\"]/,\n (match) => `${match}\\n${newDrizzleImport}`\n )\n } else {\n updatedContent = `${newDrizzleImport}\\n${updatedContent}`\n }\n }\n\n // Add sql import if needed and not present\n if (needsSql && !sqlImportExists) {\n updatedContent = `import { sql } from 'drizzle-orm'\\n${updatedContent}`\n }\n\n return updatedContent\n}\n\n/**\n * Helper function to find table end position in schema file\n */\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n let tableEnd = startIndex\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prevChar = i > 0 ? content[i - 1] : ''\n\n // Handle string literals\n if ((char === '\"' || char === \"'\" || char === '`') && prevChar !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n // Found the closing paren of pgTable()\n if (depth === 0 && char === ')') {\n tableEnd = i + 1\n break\n }\n }\n\n return tableEnd\n}\n\n/**\n * Update packages/database/src/schema.ts with new table\n */\nasync function updateSchemaFile(schema: Schema, options: GeneratorOptions): Promise<void> {\n const paths = getPaths()\n const schemaFilePath = path.join(paths.database, 'src/schema.ts')\n\n let currentContent = ''\n if (fs.existsSync(schemaFilePath)) {\n currentContent = fs.readFileSync(schemaFilePath, 'utf-8')\n }\n\n // Convert kebab-case schema names to camelCase for variable names\n const variableName = toCamelCase(schema.name)\n\n // Check if table already exists\n if (currentContent.includes(`export const ${variableName} =`) && !options.force) {\n console.warn(\n ` ⚠️ Table \"${variableName}\" already exists in schema.ts. Use --force to overwrite.`\n )\n return\n }\n\n // Track required imports\n const requiredImports = new Set<string>()\n const needsSql = { value: false }\n\n // Generate new table definition\n const newTableDef = generateSchemaDefinition(schema, requiredImports, needsSql)\n\n // Generate junction table definitions for many-to-many relationships\n const m2mFields = getManyToManyFields(schema.fields)\n const _junctionTableDefs = m2mFields\n .map((field) => generateJunctionTableDefinition(schema.name, field, requiredImports))\n .join('')\n\n // Update imports\n let updatedContent = currentContent\n if (updatedContent) {\n updatedContent = updateImports(updatedContent, requiredImports, needsSql.value)\n } else {\n // New file - create from scratch\n const sortedImports = Array.from(requiredImports).sort()\n const importsStr = needsSql.value\n ? `import { sql } from 'drizzle-orm'\\nimport {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'\\n`\n : `import {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'\\n`\n updatedContent = importsStr\n }\n\n // Add the new table definition\n if (options.force && currentContent.includes(`export const ${variableName} =`)) {\n // Replace existing definition\n const tableStart = currentContent.indexOf(`export const ${variableName} =`)\n if (tableStart !== -1) {\n const tableEnd = findTableEnd(currentContent, tableStart)\n updatedContent =\n currentContent.slice(0, tableStart) + newTableDef.trim() + currentContent.slice(tableEnd)\n }\n } else {\n // Append new definition\n updatedContent = `${updatedContent.trimEnd()}\\n${newTableDef}`\n }\n\n // Handle junction tables for many-to-many relationships\n for (const m2mField of m2mFields) {\n const singularSchema = singularize(schema.name)\n const junctionTableName = `${singularSchema}${toPascalCase(m2mField.relationship || '')}`\n const junctionVarName = toCamelCase(junctionTableName)\n\n if (options.force && updatedContent.includes(`export const ${junctionVarName} =`)) {\n // Replace existing junction table\n const junctionStart = updatedContent.indexOf(`export const ${junctionVarName} =`)\n if (junctionStart !== -1) {\n const junctionEnd = findTableEnd(updatedContent, junctionStart)\n const junctionDef = generateJunctionTableDefinition(schema.name, m2mField, requiredImports)\n updatedContent =\n updatedContent.slice(0, junctionStart) +\n junctionDef.trim() +\n updatedContent.slice(junctionEnd)\n }\n } else if (!updatedContent.includes(`export const ${junctionVarName} =`)) {\n // Append junction table\n const junctionDef = generateJunctionTableDefinition(schema.name, m2mField, requiredImports)\n updatedContent = `${updatedContent.trimEnd()}\\n${junctionDef}`\n }\n }\n\n // Re-update imports to include any new ones from junction tables\n updatedContent = updateImports(updatedContent, requiredImports, needsSql.value)\n\n fs.writeFileSync(schemaFilePath, updatedContent, 'utf-8')\n}\n\n/**\n * Remove previous migrations for a schema\n */\nfunction removePreviousMigrations(schemaName: string, migrationDir: string): void {\n try {\n const files = fs.readdirSync(migrationDir)\n const migrationPattern = new RegExp(`^\\\\d+_${schemaName}\\\\.sql$`)\n\n for (const file of files) {\n if (migrationPattern.test(file)) {\n const filePath = path.join(migrationDir, file)\n fs.unlinkSync(filePath)\n console.log(` 🗑️ Removed previous migration: ${file}`)\n }\n }\n } catch (error) {\n // If directory doesn't exist or read fails, that's okay - no migrations to remove\n if (error instanceof Error && !error.message.includes('ENOENT')) {\n console.warn(` ⚠️ Warning: Could not remove previous migrations: ${error.message}`)\n }\n }\n}\n\n/**\n * Generate database schema and migration files\n */\nexport async function generateDatabase(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string[]> {\n const paths = getPaths()\n const files: string[] = []\n\n // Update schema.ts in packages/database\n await updateSchemaFile(schema, options)\n files.push('packages/database/src/schema.ts')\n\n // Generate migration SQL in packages/database/drizzle\n const migrationDir = path.join(paths.database, 'drizzle')\n ensureDir(migrationDir)\n\n // Remove previous migrations for this schema if --force is used\n if (options.force) {\n removePreviousMigrations(schema.name, migrationDir)\n }\n\n const timestamp = getMigrationTimestamp()\n const migrationFileName = `${timestamp}_${schema.name}.sql`\n const migrationFilePath = path.join(migrationDir, migrationFileName)\n\n // Generate main table SQL\n let migrationSQL = generateMigrationSQL(schema)\n\n // Generate junction table SQL for many-to-many relationships\n const m2mFields = getManyToManyFields(schema.fields)\n for (const field of m2mFields) {\n migrationSQL += `\\n${generateJunctionTableSQL(schema.name, field)}`\n }\n\n fs.writeFileSync(migrationFilePath, migrationSQL, 'utf-8')\n files.push(`packages/database/drizzle/${migrationFileName}`)\n\n return files\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate edit page component\n */\nexport async function generateEditPage(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const editDir = path.join(paths.app, 'app/(admin)/admin', schema.name, '[id]', 'edit')\n ensureDir(editDir)\n\n const pageFilePath = path.join(editDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Edit page already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/[id]/edit/page.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const camelSingular = toCamelCase(singularName)\n\n const ir = getImportResolver()\n\n const content = `import { notFound } from 'next/navigation'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\nimport { get${pascalSingular}ById } from '${ir.actions(schema.name)}'\nimport { ${pascalSingular}Form } from '../../${schema.name}-form'\nimport { Button } from '${ir.adminUi}'\nimport Link from 'next/link'\nimport { ArrowLeft } from 'lucide-react'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n const ${camelSingular} = await get${pascalSingular}ById(Number.parseInt(id, 10))\n\n if (!${camelSingular}) {\n notFound()\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader\n title=\"Edit ${pascalSingular}\"\n description=\"Update ${singularName} information\"\n />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/${schema.name}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${schema.label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-6\">\n <${pascalSingular}Form key={${camelSingular}.id} initialData={${camelSingular}} />\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/[id]/edit/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types'\nimport { ensureDir, getPaths, toPascalCase } from '../utils'\n\n/**\n * Check if a form schema has dynamicFields\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[]): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'group' && field.fields) {\n // Recursively flatten group fields - don't include the group itself\n return flattenFields(field.fields)\n }\n // Only return non-group fields (no need to propagate conditions for email)\n // Skip dynamicFields - they're handled separately via customFields\n return field.type === 'group' || field.type === 'dynamicFields' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Get TypeScript type for a form field\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) {\n return 'Record<string, unknown>[] | null'\n }\n return 'string[] | null'\n default:\n return 'string | null'\n }\n}\n\n/**\n * Generate value display for a field in email\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\n case 'upload':\n case 'file':\n return `{${name} ? (\n <Link href={${name}} style={link}>Download File</Link>\n ) : (\n 'No file uploaded'\n )}`\n\n case 'email':\n return `{${name} ? (\n <Link href={\\`mailto:\\${${name}}\\`} style={link}>{${name}}</Link>\n ) : (\n 'N/A'\n )}`\n\n case 'url':\n return `{${name} ? (\n <Link href={${name}} style={link}>{${name}}</Link>\n ) : (\n 'N/A'\n )}`\n\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) {\n // Object list\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 'N/A'\n )}`\n }\n // Simple array\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? ${name}.join(', ') : 'N/A'}`\n\n case 'date':\n return `{${name} ? new Date(${name}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : 'N/A'}`\n\n default:\n return `{${name} ?? 'N/A'}`\n }\n}\n\n/**\n * Generate email template for form submission notifications\n */\nexport async function generateEmailTemplate(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string | null> {\n if (!schema.notificationEmail) {\n return null\n }\n\n const paths = getPaths()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const fields = getAllFields(schema).filter((f) => f.name) // Get flattened fields with names only\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Check if we need Link component\n const needsLink = fields.some(\n (f) => f.type === 'upload' || f.type === 'file' || f.type === 'email' || f.type === 'url'\n )\n\n // Check if we need listItem style (for object lists)\n const needsListItem = fields.some(\n (f) => (f.type === 'list' || f.type === 'multiselect') && f.fields && f.fields.length > 0\n )\n\n // Generate interface for email props\n const emailPropsInterfaceFields = fields\n .map((f) => ` ${f.name}: ${getTypeForField(f)}`)\n .join('\\n')\n const customFieldsLine = includeDynamicFields\n ? '\\n customFields?: Record<string, unknown> | null'\n : ''\n const emailPropsInterface = emailPropsInterfaceFields + customFieldsLine\n\n // Generate field sections for 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 // Generate custom fields section for email\n const customFieldsSection = includeDynamicFields\n ? `\n\n {/* Custom Fields (from CMS) */}\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 const propsDestructured = includeDynamicFields\n ? `${fields.map((f) => f.name).join(',\\n ')},\n customFields,\n submittedAt`\n : `${fields.map((f) => f.name).join(',\\n ')},\n submittedAt`\n\n const emailContent = `import { Body, Container, Head, Heading, Html${needsLink ? ', Link' : ''}, Preview, Row, Section, Text } from '@react-email/components'\n\ninterface ${pascalName}SubmissionEmailProps {\n${emailPropsInterface}\n submittedAt: string\n}\n\nexport function ${pascalName}SubmissionEmail({\n ${propsDestructured}\n}: ${pascalName}SubmissionEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>New ${schema.label} Submission</Preview>\n <Body style={main}>\n <Container style={container}>\n {/* Header with Logo */}\n <Section style={header}>\n <Text style={logoText}>BetterStart</Text>\n </Section>\n\n {/* Title */}\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 {/* Form Fields */}\n <Section style={card}>\n${fieldSections}${customFieldsSection}\n </Section>\n\n {/* Footer */}\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\n// Brand Colors\nconst colors = {\n primary: '#7c3aed',\n primaryDark: '#6d28d9',\n background: '#f8fafc',\n cardBg: '#ffffff',\n text: '#1e293b',\n textMuted: '#64748b',\n textLight: '#94a3b8',\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n}\n\n// Styles\nconst main = {\n backgroundColor: colors.background,\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Ubuntu, 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',\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',\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',\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\n${\n needsLink\n ? `const link = {\n color: colors.primary,\n fontWeight: '500',\n textDecoration: 'none',\n}\n\n`\n : ''\n}${\n needsListItem\n ? `const 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}${\n includeDynamicFields\n ? `const 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',\n margin: '0 0 8px',\n}\n\n`\n : ''\n}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',\n margin: '0',\n}\n`\n\n const emailPath = path.join(paths.app, 'emails', `${formName}-submission.tsx`)\n ensureDir(path.dirname(emailPath))\n\n if (fs.existsSync(emailPath) && !options.force) {\n console.warn(`⚠️ Email template already exists: ${emailPath}. Use --force to overwrite.`)\n return emailPath\n }\n\n fs.writeFileSync(emailPath, emailContent, 'utf-8')\n console.log(` ✓ Email template generated: ${emailPath}`)\n\n return emailPath\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Get form field type\n */\nfunction 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\n/**\n * Get Zod schema type\n */\nfunction 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 // Use z.number() directly - form inputs with type=\"number\" provide numbers\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 // Transform empty strings to undefined for optional date fields\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 if (!field.required) {\n // Transform empty strings to undefined for optional image fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const imageBase = `z.string().min(1, 'Please upload an image for ${label}').url('Please provide a valid image URL')`\n return field.length ? `${imageBase}.max(${field.length})` : imageBase\n }\n case 'video': {\n if (!field.required) {\n // Transform empty strings to undefined for optional video fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const videoBase = `z.string().min(1, 'Please upload a video for ${label}').url('Please provide a valid video URL')`\n return field.length ? `${videoBase}.max(${field.length})` : videoBase\n }\n case 'media': {\n if (!field.required) {\n // Transform empty strings to undefined for optional media fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const mediaBase = `z.string().min(1, 'Please upload media for ${label}').url('Please provide a valid media URL')`\n return field.length ? `${mediaBase}.max(${field.length})` : mediaBase\n }\n case 'list':\n // Handle list with nested fields (array of objects)\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .flatMap((nestedField) => {\n const defs: string[] = []\n const nestedZodType = getZodType(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 // Add icon field if hasIcon is true\n if (nestedField.hasIcon) {\n defs.push(\n ` ${quotePropertyName(`${nestedField.name}Icon`)}: z.string().optional()`\n )\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 // Handle list with items (simple string array)\n if (field.items?.type === 'string' || field.items?.type === 'varchar') {\n const itemSchema = field.items.length\n ? `z.string().max(${field.items.length})`\n : '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 case 'select': {\n // Select fields are stored as strings, validate against options if provided\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 const base = field.required\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().optional()'\n return base\n }\n case 'icon': {\n // Icon fields are stored as strings (icon names)\n const base = field.required\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().optional()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'relationship': {\n // Many-to-many relationships store array of IDs\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 // Single relationship fields store the ID of the related entity as a string\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'curriculum': {\n // Curriculum stores both items and weeks - mode determines which editor to show\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 }\n case 'group': {\n // Group fields are nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((nestedField) => {\n const nestedZodType = getZodType(nestedField)\n const alreadyOptional = nestedZodType.includes('.optional()')\n let nestedDef = ` ${quotePropertyName(nestedField.name)}: ${nestedZodType}`\n if (!nestedField.required && !alreadyOptional) {\n nestedDef += '.optional()'\n }\n return nestedDef\n })\n .join(',\\n')\n return field.required\n ? `z.object({\\n${nestedFields}\\n })`\n : `z.object({\\n${nestedFields}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n }\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Generate tab component\n */\nfunction generateTabComponent(\n tab: { name: string; label: string; fields?: SchemaField[] },\n schema: Schema,\n generateFieldJSX: (field: SchemaField, indent?: string) => string,\n toPascalCase: (str: string) => string\n): string {\n const ir = getImportResolver()\n const tabPascalName = toPascalCase(tab.name)\n const tabFields = tab.fields || []\n\n // Recursive function to check for field types at any nesting level\n function checkForFieldType(fields: SchemaField[], type: string): boolean {\n for (const f of fields) {\n if (f.type === type) return true\n if (f.type === 'group' && f.fields) {\n if (checkForFieldType(f.fields, type)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForFieldType(f.fields, type)) return true\n }\n }\n return false\n }\n\n // Check what components are needed for this tab (recursively)\n const hasBooleanField = checkForFieldType(tabFields, 'boolean')\n const hasImageField = checkForFieldType(tabFields, 'image')\n const hasVideoField = checkForFieldType(tabFields, 'video')\n const hasMediaField = checkForFieldType(tabFields, 'media')\n const hasDateField = checkForFieldType(tabFields, 'date')\n const hasListField = checkForFieldType(tabFields, 'list')\n // Check for nested list fields (list fields that contain list fields in their nested fields)\n const hasNestedListField = tabFields.some(\n (f) => f.type === 'list' && f.fields?.some((nf) => nf.type === 'list')\n )\n const hasSelectField = checkForFieldType(tabFields, 'select')\n const hasMarkdownField = checkForFieldType(tabFields, 'markdown')\n const hasRichtextField = checkForFieldType(tabFields, 'richtext')\n const hasTextareaField = checkForFieldType(tabFields, 'text')\n const hasSeparatorField = checkForFieldType(tabFields, 'separator')\n const hasCurriculumField = checkForFieldType(tabFields, 'curriculum')\n\n // Check for icon type OR hasIcon property\n function checkForIconUsage(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'icon' || f.hasIcon) return true\n if (f.type === 'group' && f.fields) {\n if (checkForIconUsage(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForIconUsage(f.fields)) return true\n }\n }\n return false\n }\n const hasIconField = checkForIconUsage(tabFields)\n\n // Check for relationship fields\n function checkForRelationshipField(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'relationship') return true\n if (f.type === 'group' && f.fields) {\n if (checkForRelationshipField(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForRelationshipField(f.fields)) return true\n }\n }\n return false\n }\n const hasRelationshipField = checkForRelationshipField(tabFields)\n\n // Collect relationship fields for imports (only top-level and group fields, not inside lists)\n function collectRelationshipFieldsTopLevel(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n if (f.type === 'relationship' && f.relationship) result.push(f)\n if (f.type === 'group' && f.fields) {\n result.push(...collectRelationshipFieldsTopLevel(f.fields))\n }\n // Don't recurse into list fields - those use uncontrolled Popover\n }\n return result\n }\n // Collect ALL relationship fields (including those in lists) for data hooks\n function collectAllRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n if (f.type === 'relationship' && f.relationship) result.push(f)\n if (f.type === 'group' && f.fields) {\n result.push(...collectAllRelationshipFields(f.fields))\n }\n if (f.type === 'list' && f.fields) {\n result.push(...collectAllRelationshipFields(f.fields))\n }\n }\n return result\n }\n const tabRelationshipFields = collectRelationshipFieldsTopLevel(tabFields)\n const tabAllRelationshipFields = collectAllRelationshipFields(tabFields)\n\n // Check for nested list fields in this tab\n const tabListFieldsWithNestedFields: SchemaField[] = []\n // Collect nested list fields (list fields inside list fields) with their parent info\n const tabNestedListFields: { parent: SchemaField; nested: SchemaField }[] = []\n function collectTabListFields(fields: SchemaField[]) {\n fields.forEach((f) => {\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n tabListFieldsWithNestedFields.push(f)\n // Check for nested lists inside this list field\n f.fields.forEach((nf) => {\n if (nf.type === 'list' && nf.fields && nf.fields.length > 0) {\n tabNestedListFields.push({ parent: f, nested: nf })\n }\n })\n }\n if (f.type === 'group' && f.fields) {\n collectTabListFields(f.fields)\n }\n })\n }\n collectTabListFields(tabFields)\n\n // Generate state for nested list accordions (using Record to track expanded state per parent index)\n // Use capitalize helper (not toPascalCase which lowercases rest of camelCase names)\n const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)\n const tabNestedListAccordionState = tabNestedListFields\n .map(\n ({ nested }) =>\n ` const [${nested.name}Expanded, set${capitalize(nested.name)}Expanded] = React.useState<Record<number, string | undefined>>({})`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n // Generate state for auto-opening relationship popovers when adding new nested list items\n const tabNestedListAutoOpenState = tabNestedListFields\n .filter(({ nested }) => nested.fields?.some((f) => f.type === 'relationship'))\n .map(\n ({ nested }) =>\n ` const [newlyAdded${capitalize(nested.name)}, setNewlyAdded${capitalize(nested.name)}] = React.useState<{ parentIndex: number; nestedIndex: number } | null>(null)`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n // Generate state for auto-opening relationship popovers when adding new regular list items (not nested lists)\n const tabListAutoOpenState = tabListFieldsWithNestedFields\n .filter((f) => f.fields?.some((nf) => nf.type === 'relationship'))\n .map(\n (field) =>\n ` const [newlyAdded${capitalize(field.name)}Item, setNewlyAdded${capitalize(field.name)}Item] = React.useState<number | null>(null)`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n const tabFieldArrayHooks = [\n tabListFieldsWithNestedFields\n .map(\n (\n field\n ) => ` const [${field.name}Expanded, set${toPascalCase(field.name)}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 tabNestedListAccordionState,\n tabNestedListAutoOpenState,\n tabListAutoOpenState\n ]\n .filter(Boolean)\n .join('\\n')\n\n // Generate relationship open state (only for top-level, not inside lists)\n const tabRelationshipOpenState = tabRelationshipFields\n .map(\n (field) =>\n ` const [${field.name}Open, set${toPascalCase(field.name)}Open] = React.useState(false)`\n )\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // Generate relationship data hooks (for ALL relationship fields including those in lists)\n const tabRelationshipDataHooks = [...new Set(tabAllRelationshipFields.map((f) => f.relationship))]\n .map((relationship) => {\n const relationshipPascal = toPascalCase(pluralize(relationship || ''))\n return ` const { data: ${relationship}Data } = use${relationshipPascal}()`\n })\n .join('\\n')\n\n const tabRelationshipHooks = [tabRelationshipOpenState, tabRelationshipDataHooks]\n .filter(Boolean)\n .join('\\n')\n\n // Helper to wrap top-level tab field with showWhen conditional\n const wrapTabFieldWithShowWhen = (fieldJSX: string, field: SchemaField, indent: string) => {\n if (!field.showWhen) return fieldJSX\n const showWhenField = field.showWhen.field\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(field.showWhen.value)) {\n const values = field.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch('${showWhenField}'))`\n } else if (field.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch('${showWhenField}') !== true`\n } else {\n showWhenCondition = `form.watch('${showWhenField}') === ${typeof field.showWhen.value === 'boolean' ? field.showWhen.value.toString() : `'${field.showWhen.value}'`}`\n }\n return `${indent}{${showWhenCondition} && (\n${fieldJSX}\n${indent})}`\n }\n\n const tabFieldsJSX = tabFields\n .map((field) => {\n const fieldJSX = generateFieldJSX(field, ' ')\n return wrapTabFieldWithShowWhen(fieldJSX, field, ' ')\n })\n .join('\\n')\n\n // Build imports for tab component\n const tabComponentImports = [\n 'FormControl',\n 'FormDescription',\n 'FormField',\n 'FormItem',\n 'FormLabel',\n 'FormMessage',\n 'Input'\n ]\n\n if (hasBooleanField) {\n tabComponentImports.push('Checkbox')\n }\n if (hasMarkdownField) {\n tabComponentImports.push('MarkdownEditor')\n }\n if (hasRichtextField) {\n tabComponentImports.push('RichTextEditor')\n }\n if (hasTextareaField) {\n tabComponentImports.push('Textarea')\n }\n if (hasImageField) {\n tabComponentImports.push('ImageUploadField')\n }\n if (hasVideoField) {\n tabComponentImports.push('VideoUploadField')\n }\n if (hasMediaField) {\n tabComponentImports.push('MediaUploadField')\n }\n if (hasDateField) {\n tabComponentImports.push('DatePicker')\n }\n if (hasCurriculumField) {\n tabComponentImports.push('CurriculumEditor')\n }\n if (hasIconField) {\n tabComponentImports.push('IconPicker')\n }\n if (hasListField) {\n tabComponentImports.push('Button', 'Label', 'Placeholder', 'Separator')\n if (tabListFieldsWithNestedFields.length > 0) {\n tabComponentImports.push('Accordion', 'AccordionContent', 'AccordionItem', 'AccordionTrigger')\n }\n }\n if (hasSeparatorField && !hasListField) {\n // Separator is already imported for list fields\n tabComponentImports.push('Separator')\n }\n if (hasSelectField) {\n tabComponentImports.push(\n 'Select',\n 'SelectContent',\n 'SelectItem',\n 'SelectTrigger',\n 'SelectValue'\n )\n }\n if (hasRelationshipField) {\n tabComponentImports.push(\n 'Button',\n 'Command',\n 'CommandEmpty',\n 'CommandGroup',\n 'CommandInput',\n 'CommandItem',\n 'CommandList',\n 'Popover',\n 'PopoverContent',\n 'PopoverTrigger'\n )\n }\n\n const tabLucideImports = (() => {\n const imports: string[] = []\n if (hasListField) imports.push('Plus', 'X')\n if (hasRelationshipField) imports.push('Check', 'ChevronsUpDown')\n if (hasNestedListField) imports.push('Trash2')\n return imports.length > 0\n ? `import { ${[...new Set(imports)].sort().join(', ')} } from 'lucide-react'`\n : ''\n })()\n const tabIconNameImport = hasIconField\n ? `import type { IconName } from 'lucide-react/dynamic'`\n : ''\n const tabMarkdownImport = hasMarkdownField\n ? `import { componentSnippets } from '${ir.libMarkdown}'`\n : ''\n const tabFieldArrayImport =\n tabListFieldsWithNestedFields.length > 0\n ? `import { useFieldArray } from 'react-hook-form'`\n : ''\n const tabRelationshipHooksImport =\n tabAllRelationshipFields.length > 0\n ? [...new Set(tabAllRelationshipFields.map((f) => f.relationship))]\n .map((relationship) => {\n const relationshipPascal = toPascalCase(pluralize(relationship || ''))\n return `import { use${relationshipPascal} } from '${ir.hooks}'`\n })\n .join('\\n')\n : ''\n const tabCnImport = hasRelationshipField ? `import { cn } from '${ir.utils}'` : ''\n\n const hasReactImport = tabListFieldsWithNestedFields.length > 0 || hasRelationshipField // Need React.useState for accordion state and combobox open state\n\n return `'use client'\n${hasReactImport ? `\\nimport * as React from 'react'` : ''}\nimport { UseFormReturn } from 'react-hook-form'${tabFieldArrayImport ? `\\n${tabFieldArrayImport}` : ''}${tabLucideImports ? `\\n${tabLucideImports}` : ''}${tabIconNameImport ? `\\n${tabIconNameImport}` : ''}${tabMarkdownImport ? `\\n${tabMarkdownImport}` : ''}${tabCnImport ? `\\n${tabCnImport}` : ''}${tabRelationshipHooksImport ? `\\n${tabRelationshipHooksImport}` : ''}\nimport {\n ${[...new Set(tabComponentImports)].sort().join(',\\n ')}\n} from '${ir.adminUi}'\nimport type { FormValues } from '../${schema.name}-form'\n\ninterface Tab${tabPascalName}Props {\n form: UseFormReturn<FormValues>\n isPending: boolean\n}\n\nexport function Tab${tabPascalName}({ form, isPending }: Tab${tabPascalName}Props) {\n${tabFieldArrayHooks ? `${tabFieldArrayHooks}\\n` : ''}${tabRelationshipHooks ? `${tabRelationshipHooks}\\n` : ''} return (\n <div className=\"space-y-5\">\n${tabFieldsJSX}\n </div>\n )\n}\n`\n}\n\n/**\n * Generate form component\n */\nexport async function generateForm(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const formFilePath = path.join(adminDir, `${schema.name}-form.tsx`)\n\n // Check if file exists\n if (fs.existsSync(formFilePath) && !options.force) {\n console.warn(` ⚠️ Form file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${schema.name}-form.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const camelSingular = toCamelCase(singularName)\n\n // Collect field names that are inside tabs (to avoid duplicates and unused hooks)\n const fieldsInTabs = new Set<string>()\n schema.fields.forEach((field) => {\n if (field.type === 'tabs' && field.tabs) {\n field.tabs.forEach((tab) => {\n if (tab.fields) {\n tab.fields.forEach((tabField) => {\n fieldsInTabs.add(tabField.name)\n // Also collect nested fields inside groups within tabs\n if (tabField.type === 'group' && tabField.fields) {\n tabField.fields.forEach((groupField) => {\n fieldsInTabs.add(groupField.name)\n // Check for nested list fields inside groups\n if (groupField.type === 'list' && groupField.fields) {\n groupField.fields.forEach((listField) => {\n fieldsInTabs.add(listField.name)\n })\n }\n })\n }\n // Check for nested list fields directly in tabs\n if (tabField.type === 'list' && tabField.fields) {\n tabField.fields.forEach((listField) => {\n fieldsInTabs.add(listField.name)\n })\n }\n })\n }\n })\n }\n })\n\n // Flatten fields for database operations (Zod schema and default values)\n // Include tabs so flattenFields can extract their nested fields, but we'll exclude tabs from Zod schema\n const allFieldsForSchema = schema.fields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'lastSynced'\n )\n const flatFields = flattenFields(allFieldsForSchema)\n\n // Generate Zod schema (exclude tabs - they're UI-only)\n const zodFields = flatFields\n .filter((field) => field.type !== 'tabs')\n .flatMap((field) => {\n const defs: string[] = []\n const zodType = getZodType(field)\n // Check if the zodType already includes .optional()\n const alreadyOptional = zodType.includes('.optional()')\n let zodDef = ` ${quotePropertyName(field.name)}: ${zodType}`\n // Only add .optional() if field is not required AND zodType doesn't already include it\n if (!field.required && !alreadyOptional) {\n zodDef += '.optional()'\n }\n defs.push(zodDef)\n // Add icon field if hasIcon is true\n if (field.hasIcon) {\n defs.push(` ${quotePropertyName(`${field.name}Icon`)}: z.string().optional()`)\n }\n return defs\n })\n .join(',\\n')\n\n // Helper function to check for markdown fields recursively (including inside lists)\n function checkForMarkdownField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'markdown') return true\n if (field.type === 'list' && field.fields) {\n if (checkForMarkdownField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForMarkdownField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForMarkdownField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Helper function to check for richtext fields recursively (including inside lists)\n function checkForRichtextField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'richtext') return true\n if (field.type === 'list' && field.fields) {\n if (checkForRichtextField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForRichtextField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForRichtextField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Helper function to check for text/textarea fields recursively (including inside lists)\n function checkForTextareaField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'text') return true\n if (field.type === 'list' && field.fields) {\n if (checkForTextareaField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForTextareaField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForTextareaField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Check if we need ImageUploadField, DatePicker, DynamicListField, Select, or Tabs\n // Check both flatFields and schema.fields to catch fields in tabs\n const hasImageField =\n flatFields.some((f) => f.type === 'image') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'image'))\n ) ||\n schema.fields.some(\n (f) => f.type === 'list' && f.fields?.some((nested) => nested.type === 'image')\n )\n const hasVideoFieldMain =\n flatFields.some((f) => f.type === 'video') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'video'))\n )\n const hasMediaFieldMain =\n flatFields.some((f) => f.type === 'media') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'media'))\n )\n const hasDateField = flatFields.some((f) => f.type === 'date')\n\n // Check for relationship fields recursively\n function checkForRelationshipFieldMain(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'relationship') return true\n if (f.type === 'group' && f.fields) {\n if (checkForRelationshipFieldMain(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForRelationshipFieldMain(f.fields)) return true\n }\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields && checkForRelationshipFieldMain(tab.fields)) return true\n }\n }\n }\n return false\n }\n const hasRelationshipField = checkForRelationshipFieldMain(schema.fields)\n\n // Collect relationship fields for imports (only non-tab fields for main form)\n function collectRelationshipFieldsMain(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n // Skip tabs - they handle their own imports\n if (f.type === 'tabs') continue\n if (f.type === 'relationship' && f.relationship && !fieldsInTabs.has(f.name)) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n result.push(...collectRelationshipFieldsMain(f.fields))\n }\n }\n return result\n }\n const mainRelationshipFields = collectRelationshipFieldsMain(schema.fields)\n // Check for icon type OR hasIcon property recursively\n function checkForIconUsageMain(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'icon' || f.hasIcon) return true\n if (f.type === 'group' && f.fields) {\n if (checkForIconUsageMain(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForIconUsageMain(f.fields)) return true\n }\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields && checkForIconUsageMain(tab.fields)) return true\n }\n }\n }\n return false\n }\n const hasIconField = checkForIconUsageMain(schema.fields)\n const hasListField = flatFields.some((f) => f.type === 'list')\n // Check for nested list fields (list fields that contain list fields in their nested fields)\n const hasNestedListField = flatFields.some(\n (f) => f.type === 'list' && f.fields?.some((nf) => nf.type === 'list')\n )\n const hasSeparatorFieldMain = flatFields.some((f) => f.type === 'separator')\n const hasSelectField = flatFields.some((f) => f.type === 'select')\n const hasMarkdownField = checkForMarkdownField(schema.fields)\n const hasRichtextField = checkForRichtextField(schema.fields)\n const hasTextareaField = checkForTextareaField(schema.fields)\n const tabsField = schema.fields.find((f) => f.type === 'tabs')\n const hasTabsField = !!tabsField\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n // Check if ALL fields are inside tabs (no standalone fields outside tabs)\n const allFieldsInTabs = (() => {\n const topLevelFields = schema.fields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'id'\n )\n return topLevelFields.length === 1 && topLevelFields[0].type === 'tabs'\n })()\n\n // Generate hint JSX if field has a hint\n function generateHintJSX(field: SchemaField, indent = ' '): string {\n if (!field.hint) return ''\n return `${indent} <FormDescription>${field.hint}</FormDescription>`\n }\n\n // Helper to wrap field JSX with showWhen conditional\n function wrapWithShowWhen(\n fieldJSX: string,\n field: SchemaField,\n indent: string,\n pathPrefix?: string\n ): string {\n if (!field.showWhen) return fieldJSX\n const showWhenField = field.showWhen.field\n const fieldPath = pathPrefix ? `\\`${pathPrefix}.${showWhenField}\\`` : `'${showWhenField}'`\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(field.showWhen.value)) {\n const values = field.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (field.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof field.showWhen.value === 'boolean' ? field.showWhen.value.toString() : `'${field.showWhen.value}'`}`\n }\n return `${indent}{${showWhenCondition} && (\n${fieldJSX}\n${indent})}`\n }\n\n // Generate a single form field JSX\n // pathPrefix is used for nested fields in lists (e.g., 'modules.${index}')\n function generateFieldJSX(\n field: SchemaField,\n indent = ' ',\n pathPrefix?: string\n ): string {\n // Hidden fields are not rendered in the form UI\n if (field.hidden) {\n return ''\n }\n\n const fieldType = getFormFieldType(field)\n const label = field.label || field.name\n const hintJSX = generateHintJSX(field, indent)\n\n // Handle group type - render nested fields in a grid\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields\n .map((nestedField) => {\n const nestedJSX = generateFieldJSX(nestedField, `${indent} `, pathPrefix)\n return wrapWithShowWhen(nestedJSX, nestedField, `${indent} `, pathPrefix)\n })\n .join('\\n')\n\n // Only show heading if label is set and not empty\n const headingJSX =\n label && label !== field.name\n ? `${indent}<h3 className=\"text-lg font-medium\">${label}</h3>\\n`\n : ''\n\n return `${indent}<div className=\"space-y-5\">\n${headingJSX}${indent} <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n${indent} </div>\n${indent}</div>`\n }\n\n // Handle separator type - render a visual separator\n if (field.type === 'separator') {\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\n if (field.type === 'image') {\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\n if (field.type === 'video') {\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\n if (field.type === 'media') {\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\n if (field.type === 'date') {\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\n if (field.type === 'select') {\n const options = field.options || []\n const optionsJSX = options\n .map(\n (opt) =>\n `${indent} <SelectItem key=\"${opt.value}\" value=\"${opt.value}\">${opt.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\n if (field.type === 'icon') {\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 as IconName | undefined}\n${indent} onValueChange={(value) => formField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (field.type === 'curriculum') {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormControl>\n${indent} <CurriculumEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} label=\"${label}\"\n${field.hint ? `${indent} hint=\"${field.hint}\"\\n` : ''}${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (field.type === 'relationship' && field.relationship) {\n const relationshipName = field.relationship\n const relationshipSingular = singularize(relationshipName)\n const relationshipPascal = toPascalCase(relationshipSingular)\n\n // Generate display field logic based on relationship type\n // For instructors: use firstName + lastName\n // For others: try name, title, or label\n let displayField: string\n if (relationshipName === 'instructors') {\n displayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else {\n // Generic fallback for other relationships - use 'in' type narrowing with string cast for type safety\n displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n\n // Access the array from the response object (e.g., instructorsData?.instructors)\n const dataArray = `${relationshipName}Data?.${relationshipName}`\n\n // Many-to-many relationship - multi-select UI\n if (field.multiple) {\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} <div className=\"flex gap-2\">\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} aria-expanded={${field.name}Open}\n${indent} className={cn(\n${indent} \"w-full justify-between min-h-10 h-auto\",\n${indent} (!formField.value || formField.value.length === 0) && \"text-muted-foreground\"\n${indent} )}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value && formField.value.length > 0\n${indent} ? (() => {\n${indent} const selectedItems = ${dataArray}?.filter((item) => \n${indent} item.id !== null && formField.value?.includes(item.id as number)\n${indent} ) || []\n${indent} if (selectedItems.length === 0) return \"Select ${label.toLowerCase()}\"\n${indent} if (selectedItems.length <= 2) {\n${indent} return selectedItems.map(item => ${displayField}).join(', ')\n${indent} }\n${indent} return \\`\\${selectedItems.length} ${label.toLowerCase()} selected\\`\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 ${relationshipSingular} 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 currentValue = formField.value || []\n${indent} const newValue = isSelected\n${indent} ? currentValue.filter((id: number) => id !== item.id)\n${indent} : [...currentValue, item.id as number]\n${indent} formField.onChange(newValue)\n${indent} }}\n${indent} >\n${indent} <Check\n${indent} className={cn(\n${indent} \"mr-2 size-4\",\n${indent} isSelected ? \"opacity-100\" : \"opacity-0\"\n${indent} )}\n${indent} />\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${indent} </div>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n // Single-value relationship - single-select combobox\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} aria-expanded={${field.name}Open}\n${indent} className={cn(\n${indent} \"w-full justify-between\",\n${indent} !formField.value && \"text-muted-foreground\"\n${indent} )}\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 ${relationshipSingular} 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\n${indent} className={cn(\n${indent} \"mr-2 size-4\",\n${indent} formField.value === String(item.id) ? \"opacity-100\" : \"opacity-0\"\n${indent} )}\n${indent} />\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\n if (field.type === 'list') {\n // Handle list with nested fields (array of objects)\n if (field.fields && field.fields.length > 0) {\n const nestedFieldsJSX = field.fields\n .map((nestedField) => {\n const nestedLabel = nestedField.label || nestedField.name\n const nestedFieldType = getFormFieldType(nestedField)\n\n // Handle nested list (list inside list)\n if (\n nestedField.type === 'list' &&\n nestedField.fields &&\n nestedField.fields.length > 0\n ) {\n const nestedListFields = nestedField.fields\n const nestedListLabel = nestedLabel\n const nestedListSingular = singularize(nestedListLabel)\n const nestedListDefaultValues = nestedListFields\n .map((f) => {\n // Use empty string for string-like fields to prevent uncontrolled-to-controlled warnings\n const isStringLike = [\n 'string',\n 'varchar',\n 'text',\n 'select',\n 'time',\n 'icon'\n ].includes(f.type)\n const isBoolean = f.type === 'boolean'\n // Use schema-defined default if available\n let defaultValue: string\n if (f.default !== undefined) {\n defaultValue =\n typeof f.default === 'string' ? `'${f.default}'` : String(f.default)\n } else if (isStringLike) {\n defaultValue = \"''\"\n } else if (isBoolean) {\n defaultValue = 'false'\n } else if (f.required) {\n defaultValue = \"''\"\n } else {\n defaultValue = 'undefined'\n }\n return `${quotePropertyName(f.name)}: ${defaultValue}`\n })\n .join(', ')\n // Helper to wrap nested list field with showWhen conditional\n const wrapWithShowWhen = (fieldJSX: string, nlf: SchemaField) => {\n if (!nlf.showWhen) return fieldJSX\n const showWhenField = nlf.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nlf.showWhen.value)) {\n const values = nlf.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nlf.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nlf.showWhen.value === 'boolean' ? nlf.showWhen.value.toString() : `'${nlf.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${fieldJSX}\n${indent} )}`\n }\n\n // Define nestedFieldCapitalized for use in nested list relationship fields\n const nestedFieldCapitalized =\n nestedField.name.charAt(0).toUpperCase() + nestedField.name.slice(1)\n\n const nestedListFieldsJSX = nestedListFields\n .map((nlf) => {\n const nlfLabel = nlf.label || nlf.name\n const nlfHint = nlf.hint\n ? `${indent} <FormDescription>${nlf.hint}</FormDescription>`\n : ''\n // Handle relationship fields in nested lists\n if (nlf.type === 'relationship' && nlf.relationship) {\n const relName = nlf.relationship\n const relSingular = singularize(relName)\n const relPascal = toPascalCase(relSingular)\n // selectedRelDisplayField uses selectedItem (for the button display)\n // relDisplayField uses item (for the map loop)\n let selectedRelDisplayField: string\n let relDisplayField: string\n if (relName === 'instructors') {\n selectedRelDisplayField = `(selectedItem.firstName && selectedItem.lastName ? \\`\\${selectedItem.firstName} \\${selectedItem.lastName}\\`.trim() : selectedItem.firstName || selectedItem.lastName || \\`${relPascal} \\${selectedItem.id ?? 'Unknown'}\\`)`\n relDisplayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else if (relName === 'posts') {\n selectedRelDisplayField = `(selectedItem.title || \\`Post \\${selectedItem.id ?? 'Unknown'}\\`)`\n relDisplayField = `(item.title || \\`Post \\${item.id ?? 'Unknown'}\\`)`\n } else {\n selectedRelDisplayField = `(('name' in selectedItem && selectedItem.name) || ('title' in selectedItem && selectedItem.title) || ('label' in selectedItem && selectedItem.label) || \\`${relPascal} \\${selectedItem.id ?? 'Unknown'}\\`) as string`\n relDisplayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n const relDataArray = `${relName}Data?.${relName}`\n const relFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <Popover\n${indent} open={newlyAdded${nestedFieldCapitalized}?.parentIndex === index && newlyAdded${nestedFieldCapitalized}?.nestedIndex === nestedIndex ? true : undefined}\n${indent} onOpenChange={(open) => { if (!open) setNewlyAdded${nestedFieldCapitalized}(null) }}\n${indent} >\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 selectedItem = ${relDataArray}?.find((item) => item.id !== null && String(item.id) === String(formField.value))\n${indent} return selectedItem ? ${selectedRelDisplayField} : \"Select ${nlfLabel.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${nlfLabel.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 h-4 w-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 ${nlfLabel.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${nlfLabel.toLowerCase()} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${relDataArray}?.map((item) => (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={${relDisplayField}}\n${indent} onSelect={() => {\n${indent} formField.onChange(item.id !== null ? String(item.id) : '')\n${indent} setNewlyAdded${nestedFieldCapitalized}(null)\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 h-4 w-4\", item.id !== null && String(item.id) === String(formField.value) ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {${relDisplayField}}\n${indent} </CommandItem>\n${indent} ))}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(relFieldJSX, nlf)\n }\n // Handle text fields as textarea\n if (nlf.type === 'text') {\n const textFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${nlfLabel.toLowerCase()}\"\n${indent} className=\"min-h-[60px] resize-y\"\n${indent} disabled={isPending}\n${indent} {...nestedListField}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(textFieldJSX, nlf)\n }\n // Handle boolean fields as checkbox\n if (nlf.type === 'boolean') {\n const booleanFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={nestedListField.value === true}\n${indent} onCheckedChange={nestedListField.onChange}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel className=\"cursor-pointer\">${nlfLabel}</FormLabel>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} </div>\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(booleanFieldJSX, nlf)\n }\n // Handle image fields with ImageUploadField\n if (nlf.type === 'image') {\n const imageFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={nestedListField.value || ''}\n${indent} onChange={nestedListField.onChange}\n${indent} onBlur={nestedListField.onBlur}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(imageFieldJSX, nlf)\n }\n // Default: string fields as input\n const stringFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"text\"\n${indent} placeholder=\"Enter ${nlfLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} {...nestedListField}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(stringFieldJSX, nlf)\n })\n .join('\\n')\n\n // Find a display field for the accordion title (prefer 'title', then relationship field's title, then first string field)\n const stringLikeTypes = ['string', 'varchar', 'text']\n const nestedListTitleField =\n nestedListFields.find((f) => f.name === 'title' && !f.showWhen) ||\n nestedListFields.find((f) => stringLikeTypes.includes(f.type) && !f.showWhen)\n const nestedListRelationshipField = nestedListFields.find(\n (f) => f.type === 'relationship' && !f.showWhen\n )\n // For auto-open popover feature, detect any relationship field (even with showWhen)\n const hasNestedListRelationship = nestedListFields.some(\n (f) => f.type === 'relationship'\n )\n\n // Check for conditional title pattern with relationship fallback\n const nestedListConditionalTitleField = nestedListFields.find(\n (f) => stringLikeTypes.includes(f.type) && f.showWhen?.value === true\n )\n // Find relationship with same toggle as title (original pattern)\n const nestedListConditionalRelationshipField = nestedListConditionalTitleField\n ? nestedListFields.find(\n (f) =>\n f.type === 'relationship' &&\n f.showWhen?.field === nestedListConditionalTitleField.showWhen?.field &&\n f.showWhen?.value === false\n )\n : null\n // Find any relationship field for title display (new pattern for different toggles)\n const nestedListAnyRelationshipField = nestedListFields.find(\n (f) => f.type === 'relationship'\n )\n\n let nestedListTitleExpression: string\n if (nestedListTitleField) {\n nestedListTitleExpression = `form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nestedListTitleField.name}\\`) || \\`${nestedListSingular} \\${nestedIndex + 1}\\``\n } else if (\n nestedListConditionalTitleField &&\n nestedListConditionalRelationshipField?.relationship\n ) {\n // Handle conditional title: check toggle, use custom title or relationship title (same toggle)\n const toggleField = nestedListConditionalTitleField.showWhen?.field\n const customTitleFieldName = nestedListConditionalTitleField.name\n const relName = nestedListConditionalRelationshipField.relationship\n const relFieldName = nestedListConditionalRelationshipField.name\n nestedListTitleExpression = `(() => {\n const isCustom = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${toggleField}\\`)\n if (isCustom) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${customTitleFieldName}\\`)\n return customTitle || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else if (\n nestedListConditionalTitleField &&\n nestedListAnyRelationshipField?.relationship\n ) {\n // Handle conditional title with separate relationship toggle (different toggles)\n const overrideToggleField = nestedListConditionalTitleField.showWhen?.field\n const customTitleFieldName = nestedListConditionalTitleField.name\n const relName = nestedListAnyRelationshipField.relationship\n const relFieldName = nestedListAnyRelationshipField.name\n nestedListTitleExpression = `(() => {\n const isOverride = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${overrideToggleField}\\`)\n if (isOverride) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${customTitleFieldName}\\`)\n if (customTitle) return customTitle\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else if (nestedListRelationshipField?.relationship) {\n // Use the selected relationship item's display field (title, name, or slug as fallback)\n const relName = nestedListRelationshipField.relationship\n const relFieldName = nestedListRelationshipField.name\n nestedListTitleExpression = `(() => {\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else {\n nestedListTitleExpression = `\\`${nestedListSingular} \\${nestedIndex + 1}\\``\n }\n const nestedListJSX = `${indent} <div className=\"space-y-2 bg-background rounded-md corner-squircle p-4 border border-border\">\n${indent} <div className=\"flex items-center justify-between\">\n${indent} <Label>${nestedListLabel}</Label>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, [...current, { ${nestedListDefaultValues} }])\n${indent} const newNestedIndex = current.length\n${indent} set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: \\`item-\\${newNestedIndex + 1}\\` }))${\n hasNestedListRelationship\n ? `\n${indent} setNewlyAdded${nestedFieldCapitalized}({ parentIndex: index, nestedIndex: newNestedIndex })`\n : ''\n }\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${nestedListSingular}\n${indent} </Button>\n${indent} </div>\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).length > 0 && (\n${indent} <Accordion\n${indent} type=\"single\"\n${indent} collapsible\n${indent} className=\"w-full gap-1 flex flex-col\"\n${indent} value={${nestedField.name}Expanded[index]}\n${indent} onValueChange={(value) => set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: value }))}\n${indent} >\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).map((_: unknown, nestedIndex: number) => (\n${indent} <AccordionItem\n${indent} key={\\`${field.name}-\\${index}-${nestedField.name}-\\${nestedIndex}\\`}\n${indent} value={\\`item-\\${nestedIndex + 1}\\`}\n${indent} className=\"p-0 border-none\"\n${indent} >\n${indent} <div className=\"space-y-3 rounded-lg corner-squircle border p-3 bg-card\">\n${indent} <AccordionTrigger className=\"flex items-center p-0 justify-between w-full\">\n${indent} <div className=\"flex items-center gap-2\">\n${indent} <span className=\"text-xs font-medium text-muted-foreground\">{nestedIndex + 1}</span>\n${indent} <h4 className=\"text-sm font-medium\">{${nestedListTitleExpression}}</h4>\n${indent} </div>\n${indent} <Button asChild variant=\"ghost\" size=\"sm\" disabled={isPending} className=\"ml-auto\">\n${indent} <span\n${indent} role=\"button\"\n${indent} tabIndex={0}\n${indent} onClick={(e) => {\n${indent} e.stopPropagation()\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, current.filter((_: unknown, i: number) => i !== nestedIndex))\n${indent} }}\n${indent} onKeyDown={(e) => {\n${indent} if (e.key === 'Enter' || e.key === ' ') {\n${indent} e.preventDefault()\n${indent} e.stopPropagation()\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, current.filter((_: unknown, i: number) => i !== nestedIndex))\n${indent} }\n${indent} }}\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-3 pt-2\">\n${indent} <Separator />\n${nestedListFieldsJSX}\n${indent} </AccordionContent>\n${indent} </div>\n${indent} </AccordionItem>\n${indent} ))}\n${indent} </Accordion>\n${indent} )}\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).length > 5 && (\n${indent} <div className=\"flex justify-end items-center gap-2\">\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, [...current, { ${nestedListDefaultValues} }])\n${indent} const newNestedIndex = current.length\n${indent} set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: \\`item-\\${newNestedIndex + 1}\\` }))${\n hasNestedListRelationship\n ? `\n${indent} setNewlyAdded${nestedFieldCapitalized}({ parentIndex: index, nestedIndex: newNestedIndex })`\n : ''\n }\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${nestedListSingular}\n${indent} </Button>\n${indent} </div>\n${indent} )}\n${indent} </div>`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}) || '')`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${nestedListJSX}\n${indent} )}`\n }\n return nestedListJSX\n }\n\n const nestedHintJSX = nestedField.hint\n ? `${indent} <FormDescription>${nestedField.hint}</FormDescription>`\n : ''\n\n if (nestedFieldType === 'textarea') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} className=\"min-h-[80px] resize-y\"\n${indent} disabled={isPending}\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedFieldType === 'markdown') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <MarkdownEditor\n${indent} value={nestedField.value}\n${indent} onChange={nestedField.onChange}\n${indent} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} componentSnippets={componentSnippets}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedFieldType === 'richtext') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <RichTextEditor\n${indent} value={nestedField.value}\n${indent} onChange={nestedField.onChange}\n${indent} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedField.type === 'icon') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={nestedField.value as IconName | undefined}\n${indent} onValueChange={(value) => nestedField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n // Handle hasIcon for nested fields - render input with IconPicker as postfix\n if (nestedField.hasIcon) {\n const iconFieldName = `${nestedField.name}Icon`\n return `${indent} <div className=\"flex gap-2 items-end\">\n${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem className=\"flex-1\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${nestedFieldType}\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${iconFieldName}\\`}\n${indent} render={({ field: iconField }) => (\n${indent} <FormItem>\n${indent} <FormLabel className=\"invisible\">Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={iconField.value as IconName | undefined}\n${indent} onValueChange={(value) => iconField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent} </div>`\n }\n // Handle checkbox for nested fields\n if (nestedFieldType === 'checkbox') {\n const checkboxJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0 rounded-md corner-squircle border p-4\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={nestedField.value === true}\n${indent} onCheckedChange={nestedField.onChange}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${nestedHintJSX ? `${nestedHintJSX.replace(`${indent} `, `${indent} `)}\\n` : ''}${indent} </div>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${checkboxJSX}\n${indent} )}`\n }\n return checkboxJSX\n }\n // Handle relationship fields inside nested lists\n if (nestedField.type === 'relationship' && nestedField.relationship) {\n const relationshipName = nestedField.relationship\n const relationshipSingular = singularize(relationshipName)\n const relationshipPascal = toPascalCase(relationshipSingular)\n\n // Generate display field logic based on relationship type\n // selectedDisplayField uses selectedItem (for the button display)\n // displayField uses item (for the map loop)\n let selectedDisplayField: string\n let displayField: string\n if (relationshipName === 'instructors') {\n selectedDisplayField = `(selectedItem.firstName && selectedItem.lastName ? \\`\\${selectedItem.firstName} \\${selectedItem.lastName}\\`.trim() : selectedItem.firstName || selectedItem.lastName || \\`${relationshipPascal} \\${selectedItem.id ?? 'Unknown'}\\`)`\n displayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else if (relationshipName === 'posts') {\n selectedDisplayField = `(selectedItem.title || \\`Post \\${selectedItem.id ?? 'Unknown'}\\`)`\n displayField = `(item.title || \\`Post \\${item.id ?? 'Unknown'}\\`)`\n } else {\n selectedDisplayField = `(('name' in selectedItem && selectedItem.name) || ('title' in selectedItem && selectedItem.title) || ('label' in selectedItem && selectedItem.label) || \\`${relationshipPascal} \\${selectedItem.id ?? 'Unknown'}\\`) as string`\n displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n\n const dataArray = `${relationshipName}Data?.${relationshipName}`\n // Use simple capitalize (first char uppercase, rest unchanged) to match state generation\n const listCapitalizedName = field.name.charAt(0).toUpperCase() + field.name.slice(1)\n\n const relationshipJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <Popover\n${indent} open={newlyAdded${listCapitalizedName}Item === index ? true : undefined}\n${indent} onOpenChange={(open) => { if (!open) setNewlyAdded${listCapitalizedName}Item(null) }}\n${indent} >\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\n${indent} \"w-full justify-between\",\n${indent} !formField.value && \"text-muted-foreground\"\n${indent} )}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value\n${indent} ? (() => {\n${indent} const selectedItem = ${dataArray}?.find(\n${indent} (item) => item.id !== null && String(item.id) === String(formField.value)\n${indent} )\n${indent} return selectedItem ? ${selectedDisplayField} : \"Select ${nestedLabel.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${nestedLabel.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 h-4 w-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 ${nestedLabel.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${nestedLabel.toLowerCase()} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.map((item) => (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={${displayField}}\n${indent} onSelect={() => {\n${indent} formField.onChange(item.id !== null ? String(item.id) : '')\n${indent} setNewlyAdded${listCapitalizedName}Item(null)\n${indent} }}\n${indent} >\n${indent} <Check\n${indent} className={cn(\n${indent} \"mr-2 h-4 w-4\",\n${indent} item.id !== null && String(item.id) === String(formField.value)\n${indent} ? \"opacity-100\"\n${indent} : \"opacity-0\"\n${indent} )}\n${indent} />\n${indent} {${displayField}}\n${indent} </CommandItem>\n${indent} ))}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${relationshipJSX}\n${indent} )}`\n }\n return relationshipJSX\n }\n // Handle select fields inside lists\n if (nestedField.type === 'select' && nestedField.options) {\n const options = nestedField.options\n const optionsJSX = options\n .map(\n (opt) =>\n `${indent} <SelectItem key=\"${opt.value}\" value=\"${opt.value}\">${opt.label}</SelectItem>`\n )\n .join('\\n')\n const selectJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Select\n${indent} value={nestedField.value}\n${indent} onValueChange={nestedField.onChange}\n${indent} disabled={isPending}\n${indent} >\n${indent} <SelectTrigger>\n${indent} <SelectValue placeholder=\"Select ${nestedLabel.toLowerCase()}\" />\n${indent} </SelectTrigger>\n${indent} <SelectContent>\n${optionsJSX}\n${indent} </SelectContent>\n${indent} </Select>\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${selectJSX}\n${indent} )}`\n }\n return selectJSX\n }\n // Handle group type fields (nested objects with sub-fields)\n if (\n nestedField.type === 'group' &&\n nestedField.fields &&\n nestedField.fields.length > 0\n ) {\n const groupFieldsJSX = nestedField.fields\n .map((groupField) => {\n const groupFieldLabel = groupField.label || groupField.name\n const groupFieldHintJSX = groupField.hint\n ? `${indent} <FormDescription>${groupField.hint}</FormDescription>`\n : ''\n const groupFieldType = getFormFieldType(groupField)\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.${groupField.name}\\`}\n${indent} render={({ field: groupFormField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${groupFieldLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${groupFieldType}\"\n${indent} placeholder=\"Enter ${groupFieldLabel.toLowerCase()}\"\n${indent} {...groupFormField}\n${indent} />\n${indent} </FormControl>\n${groupFieldHintJSX ? `${groupFieldHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n })\n .join('\\n')\n const groupJSX = `${indent} <div className=\"space-y-4\">\n${indent} <Label className=\"text-sm font-medium\">${nestedLabel}</Label>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <div className=\"pl-4 border-l-2 border-muted space-y-4\">\n${groupFieldsJSX}\n${indent} </div>\n${indent} </div>`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${groupJSX}\n${indent} )}`\n }\n return groupJSX\n }\n // Handle image fields inside lists\n if (nestedField.type === 'image') {\n const imageFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={nestedField.value || ''}\n${indent} onChange={nestedField.onChange}\n${indent} onBlur={nestedField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={10}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${imageFieldJSX}\n${indent} )}`\n }\n return imageFieldJSX\n }\n // Default field handling\n const defaultFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${nestedFieldType}\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n // For boolean false, use !== true to handle undefined initial state\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${defaultFieldJSX}\n${indent} )}`\n }\n return defaultFieldJSX\n })\n .join('\\n')\n\n // Fix template strings to use actual field name and index\n const fixedNestedFieldsJSX = nestedFieldsJSX\n .replace(/\\$\\{field\\.name\\}/g, field.name)\n .replace(/\\$\\{index\\}/g, '$' + '{index}')\n\n const listHintJSX = field.hint\n ? `${indent} <FormDescription>${field.hint}</FormDescription>\\n`\n : ''\n\n const defaultValues = field.fields\n .flatMap((f) => {\n const defaults: string[] = []\n if (f.type === 'list' || f.type === 'curriculum') {\n defaults.push(\n `${quotePropertyName(f.name)}: ${f.type === 'curriculum' ? \"{ mode: 'sequential', items: [], weeks: [] }\" : '[]'}`\n )\n } else if (f.type === 'group' && f.fields && f.fields.length > 0) {\n // Generate default values for group sub-fields\n const groupDefaults = f.fields\n .map((gf) => {\n const isStringLike = ['string', 'varchar', 'text', 'select'].includes(gf.type)\n const isBoolean = gf.type === 'boolean'\n let gfDefault: string\n if (gf.default !== undefined) {\n gfDefault =\n typeof gf.default === 'string' ? `'${gf.default}'` : String(gf.default)\n } else if (isStringLike) {\n gfDefault = \"''\"\n } else if (isBoolean) {\n gfDefault = 'false'\n } else {\n gfDefault = 'undefined'\n }\n return `${quotePropertyName(gf.name)}: ${gfDefault}`\n })\n .join(', ')\n defaults.push(`${quotePropertyName(f.name)}: { ${groupDefaults} }`)\n } else {\n // Use empty string for string-like fields to prevent uncontrolled-to-controlled warnings\n const isStringLike = ['string', 'varchar', 'text', 'select', 'time', 'icon'].includes(\n f.type\n )\n const isNumber = ['number', 'serial', 'decimal'].includes(f.type)\n const isBoolean = f.type === 'boolean'\n // Use schema-defined default if available\n let defaultValue: string\n if (f.default !== undefined) {\n defaultValue = typeof f.default === 'string' ? `'${f.default}'` : String(f.default)\n } else if (isStringLike) {\n defaultValue = \"''\"\n } else if (isNumber) {\n defaultValue = '0'\n } else if (isBoolean) {\n defaultValue = 'false'\n } else if (f.required) {\n defaultValue = \"''\"\n } else {\n defaultValue = 'undefined'\n }\n defaults.push(`${quotePropertyName(f.name)}: ${defaultValue}`)\n }\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n defaults.push(`${quotePropertyName(`${f.name}Icon`)}: ''`)\n }\n return defaults\n })\n .join(', ')\n\n const singularLabel = singularize(label)\n const placeholderDescription =\n field.hint || `${label} is a list of items that can be added to the form.`\n\n // Find the first string-like field to use as accordion header (prioritize 'title' or 'name', then first text field, then relationship field)\n // Skip fields with showWhen conditions as they're not always visible\n const stringLikeTypes = ['string', 'varchar', 'text']\n const titleField =\n field.fields.find(\n (f) => f.name === 'title' && stringLikeTypes.includes(f.type) && !f.showWhen\n ) ||\n field.fields.find(\n (f) => f.name === 'name' && stringLikeTypes.includes(f.type) && !f.showWhen\n ) ||\n field.fields.find((f) => stringLikeTypes.includes(f.type) && !f.showWhen)\n // Find relationship field that's either unconditional or shows by default (showWhen.value === false)\n const relationshipField = field.fields.find(\n (f) => f.type === 'relationship' && (!f.showWhen || f.showWhen.value === false)\n )\n // For auto-open popover feature, detect any relationship field (even with showWhen)\n const hasAnyRelationshipField = field.fields?.some((f) => f.type === 'relationship')\n\n // Find conditional title field pattern: a string field shown when a toggle is true,\n // paired with a relationship shown when the same toggle is false\n const conditionalTitleField = field.fields.find(\n (f) =>\n stringLikeTypes.includes(f.type) &&\n f.showWhen?.value === true &&\n // Check if there's a matching relationship with opposite condition\n field.fields?.some(\n (rel) =>\n rel.type === 'relationship' &&\n rel.showWhen?.field === f.showWhen?.field &&\n rel.showWhen?.value === false\n )\n )\n const conditionalRelationshipField = conditionalTitleField\n ? field.fields.find(\n (f) =>\n f.type === 'relationship' &&\n f.showWhen?.field === conditionalTitleField.showWhen?.field &&\n f.showWhen?.value === false\n )\n : null\n\n let accordionTitle: string\n if (titleField) {\n accordionTitle = `{form.watch(\\`${field.name}.\\${index}.${titleField.name}\\`) || '${singularLabel} ' + (index + 1)}`\n } else if (conditionalTitleField && conditionalRelationshipField?.relationship) {\n // Handle conditional title: check toggle, use custom title or relationship title\n const toggleField = conditionalTitleField.showWhen?.field\n const customTitleFieldName = conditionalTitleField.name\n const relName = conditionalRelationshipField.relationship\n const relFieldName = conditionalRelationshipField.name\n accordionTitle = `{(() => {\n const isCustom = form.watch(\\`${field.name}.\\${index}.${toggleField}\\`)\n if (isCustom) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${customTitleFieldName}\\`)\n return customTitle || '${singularLabel} ' + (index + 1)\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || '${singularLabel} ' + (index + 1)\n })()}`\n } else if (relationshipField?.relationship) {\n // Use the selected relationship item's display field (title, name, or slug as fallback)\n const relName = relationshipField.relationship\n const relFieldName = relationshipField.name\n accordionTitle = `{(() => {\n const selectedId = form.watch(\\`${field.name}.\\${index}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || '${singularLabel} ' + (index + 1)\n })()}`\n } else {\n accordionTitle = `${singularLabel} {index + 1}`\n }\n\n const pascalFieldName = toPascalCase(field.name)\n // Use simple capitalize (first char uppercase, rest unchanged) to match state generation\n const capitalizedFieldName = field.name.charAt(0).toUpperCase() + field.name.slice(1)\n const dataAttrName = field.name.toLowerCase() // Data attributes must be lowercase\n const autoOpenLine = hasAnyRelationshipField\n ? `\\n${indent} setNewlyAdded${capitalizedFieldName}Item(newIndex - 1)`\n : ''\n const appendAndExpand = `{\n${indent} ${field.name}FieldArray.append({${defaultValues}})\n${indent} const newIndex = ${field.name}FieldArray.fields.length + 1\n${indent} set${pascalFieldName}Expanded(\\`item-\\${newIndex}\\`)${autoOpenLine}\n${indent} // Focus first input after accordion animation\n${indent} setTimeout(() => {\n${indent} const newItem = document.querySelector(\\`[data-${dataAttrName}-index=\"\\${newIndex - 1}\"] input\\`)\n${indent} if (newItem instanceof HTMLElement) newItem.focus()\n${indent} }, 100)\n${indent} }`\n\n return `${indent}<FormItem>\n${indent} {${field.name}FieldArray.fields.length === 0 && (\n${indent} <Placeholder\n${indent} label=\"No ${label.toLowerCase()} added yet. Click 'Add ${singularLabel}' to get started.\"\n${indent} description=\"${placeholderDescription}\"\n${indent} action={\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"lg\"\n${indent} onClick={() => ${appendAndExpand}}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} }\n${indent} />\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={() => ${appendAndExpand}}\n${indent} disabled={isPending || ${\n field.maxItems ? `${field.name}FieldArray.fields.length >= ${field.maxItems}` : 'false'\n }}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${listHintJSX ? listHintJSX : ''}${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} data-${dataAttrName}-index={index}\n${indent} >\n${indent} <div\n${indent} key={item.id}\n${indent} className=\"space-y-5 rounded-lg border p-4 bg-secondary/50 corner-squircle [&_h3]:m-0 w-full\"\n${indent} >\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) => {\n${indent} e.stopPropagation();\n${indent} ${field.name}FieldArray.remove(index);\n${indent} }}\n${indent} onKeyDown={(e) => {\n${indent} if (e.key === 'Enter' || e.key === ' ') {\n${indent} e.preventDefault();\n${indent} e.stopPropagation();\n${indent} ${field.name}FieldArray.remove(index);\n${indent} }\n${indent} }}\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\n${indent} <div className=\"space-y-5\">\n${fixedNestedFieldsJSX}\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 // Handle simple string list\n return `${indent}<DynamicListField\n${indent} name=\"${field.name}\"\n${indent} label=\"${label}\"\n${indent} disabled={isPending}\n${indent} ${field.maxItems ? `maxItems={${field.maxItems}}` : ''}\n${indent} placeholder=\"Enter ${field.items?.label?.toLowerCase() || 'value'}\"\n${indent}/>`\n }\n\n if (fieldType === 'checkbox') {\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 rounded-md corner-squircle border p-4\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={formField.value === true}\n${indent} onCheckedChange={formField.onChange}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${label}</FormLabel>\n${hintJSX ? `${hintJSX.replace(`${indent} `, `${indent} `)}\\n` : ''}${indent} </div>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (fieldType === 'textarea') {\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-[80px] resize-y\"\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\n if (fieldType === 'markdown') {\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} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} componentSnippets={componentSnippets}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (fieldType === 'richtext') {\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-[200px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n // Handle hasIcon - render input with IconPicker as postfix\n if (field.hasIcon) {\n const iconFieldName = `${field.name}Icon`\n return `${indent}<div className=\"flex gap-2 items-end\">\n${indent} <FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex-1\">\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${indent} <FormField\n${indent} control={form.control}\n${indent} name=\"${iconFieldName}\"\n${indent} render={({ field: iconField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={iconField.value as IconName | undefined}\n${indent} onValueChange={(value) => iconField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent}</div>`\n }\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} <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 // Generate form fields with support for groups and tabs\n // Include tabs from schema.fields (not formFields since we filtered them out)\n const allFormFields = schema.fields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'lastSynced'\n )\n\n // Check for draft mode - published field is auto-added when draft mode is enabled\n const hasDraftMode = schema.actions?.draft === true\n const showDraftFeatures = hasDraftMode\n\n // Collect list fields with nested fields that need useFieldArray hooks\n // Only collect fields that are NOT inside tabs (tabs handle their own hooks)\n const listFieldsWithNestedFields: SchemaField[] = []\n\n function collectListFields(fields: SchemaField[]) {\n fields.forEach((f) => {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n // Only add if not inside tabs (tabs handle their own hooks)\n if (!fieldsInTabs.has(f.name)) {\n listFieldsWithNestedFields.push(f)\n }\n }\n // Recursively check inside groups (but skip tabs since we already handled them)\n if (f.type === 'group' && f.fields) {\n collectListFields(f.fields)\n }\n // Skip tabs - they handle their own hooks\n })\n }\n\n collectListFields(allFormFields)\n\n // Generate useFieldArray hooks for list fields with nested fields (only those NOT in tabs)\n const fieldArrayHooks = listFieldsWithNestedFields\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 formFieldsJSX = allFormFields\n // Hide published field from form when draft mode is enabled (use Publish/Unpublish buttons instead)\n .filter((field) => !(showDraftFeatures && field.name === 'published'))\n .map((field) => {\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n\n const groupFields = field.fields\n .map((nestedField) => {\n const nestedJSX = generateFieldJSX(nestedField, ' ')\n return wrapWithShowWhen(nestedJSX, nestedField, ' ')\n })\n .join('\\n')\n\n const groupJSX = ` <div className=\"space-y-5\">\n <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n </div>\n </div>`\n // Wrap the entire group with showWhen if it has one\n return wrapWithShowWhen(groupJSX, field, ' ')\n }\n\n if (field.type === 'tabs' && field.tabs) {\n const tabsList = field.tabs\n .map((tab) => ` <TabsTrigger value=\"${tab.name}\">${tab.label}</TabsTrigger>`)\n .join('\\n')\n\n const tabsContent = field.tabs\n .map((tab) => {\n const tabPascalName = toPascalCase(tab.name)\n return ` <TabsContent value=\"${tab.name}\" className=\"space-y-6 p-6 rounded-2xl corner-squircle border bg-card\">\n <Tab${tabPascalName} form={form} isPending={isPending} />\n </TabsContent>`\n })\n .join('\\n')\n\n return ` <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n </Tabs>`\n }\n\n // Skip fields that are already inside tabs to avoid duplicates\n if (fieldsInTabs.has(field.name)) {\n return ''\n }\n\n const fieldJSX = generateFieldJSX(field)\n return wrapWithShowWhen(fieldJSX, field, ' ')\n })\n .filter((jsx) => jsx !== '') // Remove empty strings\n .join('\\n')\n\n // Build imports based on field types\n const componentImports = [\n 'Button',\n 'Form',\n 'FormControl',\n 'FormDescription',\n 'FormField',\n 'FormItem',\n 'FormLabel',\n 'FormMessage',\n 'Input'\n ]\n\n if (flatFields.some((f) => f.type === 'boolean')) {\n componentImports.push('Checkbox')\n }\n if (hasMarkdownField) {\n componentImports.push('MarkdownEditor')\n }\n if (hasRichtextField) {\n componentImports.push('RichTextEditor')\n }\n if (hasTextareaField) {\n componentImports.push('Textarea')\n }\n if (hasImageField) {\n componentImports.push('ImageUploadField')\n }\n if (hasVideoFieldMain) {\n componentImports.push('VideoUploadField')\n }\n if (hasMediaFieldMain) {\n componentImports.push('MediaUploadField')\n }\n if (hasDateField) {\n componentImports.push('DatePicker')\n }\n if (hasIconField) {\n componentImports.push('IconPicker')\n }\n if (hasSeparatorFieldMain && !hasListField) {\n // Separator is already imported for list fields\n componentImports.push('Separator')\n }\n if (hasListField) {\n componentImports.push('DynamicListField', 'Label', 'Placeholder', 'Separator')\n // Add Accordion components for list fields with nested fields\n // Check schema.fields directly (including inside tabs) for list fields with nested fields\n const hasListWithNestedFields = (() => {\n // Check top-level fields\n if (schema.fields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)) {\n return true\n }\n // Check inside tabs\n if (\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) =>\n tab.fields?.some(\n (field) => field.type === 'list' && field.fields && field.fields.length > 0\n )\n )\n )\n ) {\n return true\n }\n // Check inside groups\n if (\n schema.fields.some(\n (f) =>\n f.type === 'group' &&\n f.fields?.some(\n (field) => field.type === 'list' && field.fields && field.fields.length > 0\n )\n )\n ) {\n return true\n }\n return false\n })()\n if (hasListWithNestedFields) {\n componentImports.push('Accordion', 'AccordionContent', 'AccordionItem', 'AccordionTrigger')\n }\n }\n if (hasSelectField) {\n componentImports.push('Select', 'SelectContent', 'SelectItem', 'SelectTrigger', 'SelectValue')\n }\n if (hasTabsField) {\n componentImports.push('Tabs', 'TabsList', 'TabsTrigger', 'TabsContent')\n }\n if (hasRelationshipField) {\n componentImports.push(\n 'Command',\n 'CommandEmpty',\n 'CommandGroup',\n 'CommandInput',\n 'CommandItem',\n 'CommandList',\n 'Popover',\n 'PopoverContent',\n 'PopoverTrigger'\n )\n }\n\n // Generate relationship hook imports for main form\n const mainRelationshipHooksImport =\n mainRelationshipFields.length > 0\n ? mainRelationshipFields\n .map((f) => {\n const relationshipPascal = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relationshipPascal} } from '${ir.hooks}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i) // Remove duplicates\n .join('\\n')\n : ''\n\n // Generate lucide imports\n const lucideImports = (() => {\n const imports: string[] = []\n if (hasListField) imports.push('Plus', 'X')\n if (hasRelationshipField) imports.push('Check', 'ChevronsUpDown')\n if (hasNestedListField) imports.push('Trash2')\n return imports.length > 0\n ? `\\nimport { ${[...new Set(imports)].sort().join(', ')} } from 'lucide-react'`\n : ''\n })()\n\n const needsReactImport =\n mainRelationshipFields.length > 0 || listFieldsWithNestedFields.length > 0\n\n const content = `'use client'\n${needsReactImport ? `\\nimport * as React from 'react'` : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideImports}${hasIconField ? `\\nimport type { IconName } from 'lucide-react/dynamic'` : ''}\nimport { useRouter } from 'next/navigation'\nimport {${listFieldsWithNestedFields.length > 0 ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'${hasTabsField ? `\\nimport { useQueryState } from 'nuqs'` : ''}${hasMarkdownField ? `\\nimport { componentSnippets } from '${ir.libMarkdown}'` : ''}${hasRelationshipField ? `\\nimport { cn } from '${ir.utils}'` : ''}${mainRelationshipHooksImport ? `\\n${mainRelationshipHooksImport}` : ''}\nimport {\n ${[...new Set(componentImports)].sort().join(',\\n ')}\n} from '${ir.adminUi}'${showDraftFeatures ? `\\nimport { use${pascalSingular} } from '${ir.hooks}'` : ''}\nimport type {\n Create${pascalSingular}Input,\n ${pascalSingular}Data,\n Update${pascalSingular}Input\n} from '${ir.actions(schema.name)}'\nimport { create${pascalSingular}, update${pascalSingular} } from '${ir.actions(schema.name)}'${\n hasTabsField && tabsField?.tabs\n ? `\\n${tabsField.tabs\n .map((tab) => {\n const tabPascalName = toPascalCase(tab.name)\n return `import { Tab${tabPascalName} } from './tabs/tab-${tab.name}'`\n })\n .join('\\n')}`\n : ''\n }\n\nconst formSchema = z.object({\n${zodFields}\n})\n\nexport type FormValues = z.infer<typeof formSchema>\n\ninterface ${pascalSingular}FormProps {\n initialData?: ${pascalSingular}Data\n}\n\nexport function ${pascalSingular}Form({ initialData }: ${pascalSingular}FormProps) {\n const router = useRouter()\n const queryClient = useQueryClient()${\n hasTabsField\n ? `\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${firstTabName}' })`\n : ''\n }${\n mainRelationshipFields.length > 0\n ? `\\n${mainRelationshipFields\n .map((f) => {\n const relationshipPascal = 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${relationshipPascal}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')}`\n : ''\n }${\n showDraftFeatures\n ? `\n \n // Use React Query to fetch ${singularName} data if we have an ID - this will auto-update when cache is invalidated\n const { data: ${camelSingular}Data } = use${pascalSingular}(initialData?.id ?? null)\n \n // Use query data if available, otherwise fall back to initialData\n const ${camelSingular} = ${camelSingular}Data ?? initialData\n const published = ${camelSingular}?.published ?? false`\n : ''\n }\n\n const createMutation = useMutation({\n mutationFn: (data: Create${pascalSingular}Input) => create${pascalSingular}(data),\n onSuccess: async () => {\n toast.success('${pascalSingular} created successfully')\n await queryClient.invalidateQueries({ queryKey: ['${pluralName}'] })\n router.push('/admin/${schema.name}')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to create ${singularName}')\n }\n })\n\n const updateMutation = useMutation({\n mutationFn: (data: Update${pascalSingular}Input) => update${pascalSingular}(data),\n onMutate: async (newData) => {\n // Optimistically update the cache\n if (initialData?.id) {\n queryClient.setQueryData(['${singularName}', initialData.id], (oldData: ${pascalSingular}Data | undefined) => {\n if (oldData) {\n return { ...oldData, ...newData${showDraftFeatures ? ', published: newData.published' : ''} }\n }\n return oldData\n })\n }\n },\n onSuccess: (data) => {\n toast.success('${pascalSingular} updated successfully')\n // Update the query cache with the server response\n if (data.${camelSingular} && initialData?.id) {\n queryClient.setQueryData(['${singularName}', initialData.id], data.${camelSingular})\n }\n // Invalidate list cache lazily - no await so UI stays responsive\n queryClient.invalidateQueries({ queryKey: ['${pluralName}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update ${singularName}')\n }\n })\n\n const isPending = createMutation.isPending || updateMutation.isPending${\n showDraftFeatures\n ? `\n const isCreating = createMutation.isPending\n const isUpdating = updateMutation.isPending`\n : ''\n }\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${flatFields\n .filter((f) => f.type !== 'tabs')\n .flatMap((f) => {\n const defaults: string[] = []\n // Handle defaults based on field type\n if (f.type === 'list') {\n // Check if the list has nested relationship fields (direct or in nested lists) that need ID extraction\n const hasDirectRelationships = f.fields?.some((nf) => nf.type === 'relationship')\n const hasNestedListRelationships = f.fields?.some(\n (nf) => nf.type === 'list' && nf.fields?.some((nnf) => nnf.type === 'relationship')\n )\n const needsConversion = hasDirectRelationships || hasNestedListRelationships\n\n if (needsConversion && f.fields) {\n // Generate code to convert relationship objects to IDs\n const relationshipFields = f.fields.filter((nf) => nf.type === 'relationship')\n\n // Check if there are nested lists that also need conversion\n const nestedLists = f.fields.filter(\n (nf) => nf.type === 'list' && nf.fields?.some((nnf) => nnf.type === 'relationship')\n )\n\n const fieldConversions: string[] = []\n\n // Add conversions for direct relationship fields\n for (const rf of relationshipFields) {\n fieldConversions.push(\n ` ${rf.name}: item.${rf.name} ? (typeof item.${rf.name} === 'object' ? String((item.${rf.name} as { id: unknown }).id) : String(item.${rf.name})) : undefined`\n )\n }\n\n // Add conversions for nested list fields with relationships and booleans\n for (const nl of nestedLists) {\n const nestedRelFields = nl.fields!.filter((nnf) => nnf.type === 'relationship')\n const nestedBoolFields = nl.fields!.filter((nnf) => nnf.type === 'boolean')\n\n const nestedConversions: string[] = []\n\n // Handle relationship fields\n for (const nrf of nestedRelFields) {\n nestedConversions.push(\n ` ${nrf.name}: nestedItem.${nrf.name} ? (typeof nestedItem.${nrf.name} === 'object' ? String((nestedItem.${nrf.name} as { id: unknown }).id) : String(nestedItem.${nrf.name})) : undefined`\n )\n }\n\n // Handle boolean fields - coerce null/undefined to default (or false)\n for (const nbf of nestedBoolFields) {\n const defaultVal = nbf.default !== undefined ? String(nbf.default) : 'false'\n nestedConversions.push(\n ` ${nbf.name}: (nestedItem.${nbf.name} as boolean | null | undefined) ?? ${defaultVal}`\n )\n }\n\n const nestedConversionsStr = nestedConversions.join(',\\n')\n\n fieldConversions.push(` ${nl.name}: (item.${nl.name} as Record<string, unknown>[] | undefined)?.map((nestedItem: Record<string, unknown>) => ({\n ...nestedItem,\n${nestedConversionsStr}\n })) ?? []`)\n }\n\n defaults.push(` ${f.name}: initialData?.${f.name}?.map((item: Record<string, unknown>) => ({\n ...item,\n${fieldConversions.join(',\\n')}\n })) ?? []`)\n } else {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? []`)\n }\n } else if (f.type === 'curriculum') {\n // Curriculum fields are objects with mode and items/weeks\n defaults.push(` ${f.name}: initialData?.${f.name} ?? { mode: 'sequential', items: [] }`)\n } else if (f.type === 'boolean') {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? false`)\n } else if (f.type === 'number' || f.type === 'decimal' || f.type === 'serial') {\n const defaultVal = f.required ? '0' : 'undefined'\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ${defaultVal}`)\n } else if (f.type === 'relationship') {\n // Many-to-many relationships are arrays of IDs\n if (f.multiple) {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? []`)\n } else {\n // Single relationship fields are strings (storing the ID as string)\n // But when fetched from the database, they may be objects (joined data)\n // So we need to extract the ID if it's an object\n defaults.push(` ${f.name}: initialData?.${f.name} \n ? (typeof initialData.${f.name} === 'object' ? String(initialData.${f.name}.id) : String(initialData.${f.name}))\n : ''`)\n }\n } else if (f.type === 'date' || f.type === 'timestamp') {\n // Date fields can use undefined since DatePicker handles it\n defaults.push(` ${f.name}: initialData?.${f.name} ?? undefined`)\n } else if (f.default !== undefined && f.default !== null) {\n // For string fields, check if there's a default value in schema\n const defaultStr = typeof f.default === 'string' ? `'${f.default}'` : f.default\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ${defaultStr}`)\n } else {\n // All other fields (string, varchar, text, select, time, image) use empty string\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ''`)\n }\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n defaults.push(` ${f.name}Icon: initialData?.${f.name}Icon ?? ''`)\n }\n return defaults\n })\n .join(',\\n')}\n }\n })\n\n${fieldArrayHooks ? `${fieldArrayHooks}\\n` : ''}\n function onSubmit(values: FormValues${showDraftFeatures ? ', publishedValue: boolean = false' : ''}) {\n // Convert undefined to empty string for optional string fields to ensure proper serialization\n const cleanedValues = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n value === undefined ? '' : value\n ])\n ) as FormValues\n \n if (initialData) {\n updateMutation.mutate({\n id: initialData.id as number,\n ...cleanedValues${showDraftFeatures ? ',\\n published: publishedValue' : ''}\n })\n } else {\n // Exclude id field when creating since it's not part of Create*Input types\n const { id: _id, ...createValues } = cleanedValues\n createMutation.mutate({\n ...createValues${showDraftFeatures ? ',\\n published: publishedValue' : ''}\n } as Create${pascalSingular}Input)\n }\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-form\" onSubmit={form.handleSubmit((values) => onSubmit(values${showDraftFeatures ? ', 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=\"${allFieldsInTabs ? 'space-y-6' : 'space-y-6 p-6 rounded-2xl corner-squircle 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('/admin/${schema.name}')}\n disabled={isPending}\n size=\"lg\"\n >\n Cancel\n </Button>\n${\n showDraftFeatures\n ? `\n {!initialData ? (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isCreating ? '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 {isCreating ? 'Publishing...' : 'Publish'}\n </Button>\n </>\n ) : published ? (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isUpdating ? 'Unpublishing...' : 'Unpublish'}\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 {isUpdating ? 'Updating...' : 'Update'}\n </Button>\n </>\n ) : (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isUpdating ? '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 {isUpdating ? 'Publishing...' : 'Publish'}\n </Button>\n </>\n )}`\n : `\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 // Generate tab component files if tabs exist\n if (hasTabsField && tabsField?.tabs) {\n const tabsDir = path.join(adminDir, 'tabs')\n ensureDir(tabsDir)\n\n tabsField.tabs.forEach((tab) => {\n const tabComponentPath = path.join(tabsDir, `tab-${tab.name}.tsx`)\n\n // Check if file exists\n if (fs.existsSync(tabComponentPath) && !options.force) {\n console.warn(\n ` ⚠️ Tab component file already exists: tab-${tab.name}.tsx. Use --force to overwrite.`\n )\n return\n }\n\n const tabComponentContent = generateTabComponent(tab, schema, generateFieldJSX, toPascalCase)\n\n fs.writeFileSync(tabComponentPath, tabComponentContent, 'utf-8')\n console.log(` ✓ Generated tab component: tabs/tab-${tab.name}.tsx`)\n })\n }\n\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${schema.name}-form.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormColumn, FormField, FormSchema, GeneratorOptions } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n toCamelCase,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Check if a form schema has dynamicFields\n * Dynamic fields are stored in customFields JSON column\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n * Propagates group conditions to child fields\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[], parentCondition?: string): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'group' && field.fields) {\n // Combine parent condition with group condition\n const combinedCondition =\n parentCondition && field.condition\n ? `(${parentCondition}) && (${field.condition})`\n : parentCondition || field.condition\n // Recursively flatten group fields with inherited condition\n return flattenFields(field.fields, combinedCondition)\n }\n // For non-group fields, inherit the parent condition if field doesn't have its own\n if (parentCondition && !field.condition) {\n return [{ ...field, condition: parentCondition }]\n }\n // If field has its own condition and there's a parent condition, combine them\n if (parentCondition && field.condition) {\n return [{ ...field, condition: `(${parentCondition}) && (${field.condition})` }]\n }\n return field.type === 'group' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Generate custom column definition\n */\nfunction generateCustomColumnDef(col: FormColumn): string {\n const sortableHeader = col.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 ${col.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${col.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n }`\n : `header: '${col.header}'`\n\n let cellDef = ''\n\n // Generate cell content based on column type\n const _cellContent = ''\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 * Generate admin page for form submissions\n */\nexport async function generateFormAdminPages(\n schema: FormSchema,\n _options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const formName = toCamelCase(schema.name)\n const kebabName = toKebabCase(schema.name)\n const pascalName = toPascalCase(schema.name)\n const pascalSubmissionName = `${pascalName}Submission`\n const pascalSubmissionsName = `${pascalName}Submissions`\n const submissionName = `${formName}Submission`\n\n // Admin page path: /admin/forms/<form-name>\n const adminPageDir = path.join(paths.app, `app/(admin)/admin/forms/${kebabName}`)\n ensureDir(adminPageDir)\n\n const fields = getAllFields(schema)\n\n // Generate page.tsx\n await generatePageComponent(adminPageDir, pascalSubmissionsName, kebabName)\n\n // Generate columns.tsx\n await generateColumnsComponent(\n adminPageDir,\n fields,\n pascalSubmissionName,\n submissionName,\n kebabName,\n schema.columns\n )\n\n // Generate submissions-table.tsx\n await generateTableComponent(\n adminPageDir,\n pascalSubmissionsName,\n pascalSubmissionName,\n submissionName,\n schema.label,\n kebabName\n )\n\n // Generate submissions-page-content.tsx\n await generatePageContentComponent(\n adminPageDir,\n pascalSubmissionsName,\n pascalSubmissionName,\n submissionName,\n schema.label,\n kebabName\n )\n\n // Generate view page (always generated)\n const includeDynamicFields = hasDynamicFields(schema)\n await generateViewPage(\n adminPageDir,\n pascalSubmissionName,\n fields,\n schema.label,\n kebabName,\n includeDynamicFields\n )\n\n // Generate settings page for webhook configuration\n await generateSettingsPage(adminPageDir, formName, schema.label, kebabName)\n\n console.log(` - Admin UI: apps/web/app/(admin)/admin/forms/${kebabName}/`)\n}\n\n/**\n * Generate page.tsx\n */\nasync function generatePageComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n kebabName: string\n): Promise<void> {\n const content = `import * as React from 'react'\nimport { AdminSubHeader } from '@/components/admin'\nimport { AdminPageSkeleton } from '@/components/admin/admin-page-skeleton'\nimport { ${pascalSubmissionsName}PageContent } from './${kebabName}-submissions-page-content'\nimport { columns } from './columns'\n\nexport default function Page() {\n return (\n <React.Suspense fallback={<AdminPageSkeleton />}>\n <div className=\"flex flex-col\">\n <AdminSubHeader />\n <${pascalSubmissionsName}PageContent columns={columns} />\n </div>\n </React.Suspense>\n )\n}\n`\n\n fs.writeFileSync(path.join(adminPageDir, 'page.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate columns.tsx with table columns definition\n */\nasync function generateColumnsComponent(\n adminPageDir: string,\n fields: FormField[],\n pascalSubmissionName: string,\n _submissionName: string,\n kebabName: string,\n customColumns?: FormColumn[]\n): Promise<void> {\n const ir = getImportResolver()\n // Generate column definitions - use custom columns if provided, otherwise auto-generate from fields\n const columnDefs = customColumns\n ? customColumns.map((col) => generateCustomColumnDef(col)).join(',\\n')\n : fields\n .filter((field) => field.name) // Filter out fields without names (like groups)\n .map((field) => {\n const accessor = toCamelCase(field.name!)\n const label = field.label\n\n return ` {\n accessorKey: '${accessor}',\n header: ({ column }) => {\n return (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${label}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n },\n cell: ({ row }) => {\n const value = row.getValue('${accessor}')\n return <div>${field.type === 'textarea' ? \"{value ? String(value).substring(0, 100) + (String(value).length > 100 ? '...' : '') : '-'}\" : \"{value || '-'}\"}</div>\n }\n }`\n })\n .join(',\\n')\n\n // Determine required imports based on column types\n const hasBadge = customColumns?.some((c) => c.type === 'badge') || false\n\n const content = `'use client'\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n ${hasBadge ? 'Badge,' : ''}\n Button,\n Checkbox\n} from '${ir.adminUi}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\nimport { delete${pascalSubmissionName} } from '${ir.actions(`${kebabName}-form`)}'\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 * as React from 'react'\nimport { toast } from 'sonner'\n\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${pascalSubmissionName}(id)\n\n if (result.success) {\n toast.success('Submission deleted successfully')\n // Refetch the list\n queryClient.refetchQueries({ queryKey: ['${kebabName}-submissions'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submission')\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 submission \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete submission</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 submission.\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\nexport const columns: ColumnDef<${pascalSubmissionName}Data>[] = [\n {\n id: 'select',\n header: ({ table }) => (\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n }\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => 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\" className=\"size-8\" asChild>\n <Link href={\\`/admin/forms/${kebabName}/\\${submission.id}/view\\`}>\n <Eye className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">View submission</span>\n </Link>\n </Button>\n <DeleteAction id={submission.id as number} />\n </div>\n )\n }\n }\n]\n`\n\n fs.writeFileSync(path.join(adminPageDir, 'columns.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate submissions-table.tsx with data table logic\n */\nasync function generateTableComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n pascalSubmissionName: string,\n _submissionName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const hookName = `use${pascalSubmissionsName}`\n\n const content = `'use client'\n\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '${ir.adminUi}'\nimport { ${hookName} } from '${ir.hooks}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\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'\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 ${pascalSubmissionsName}TableProps<TValue> {\n columns: ColumnDef<${pascalSubmissionName}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string\n}\n\nexport function ${pascalSubmissionsName}Table<TValue>({\n columns,\n selectedIds,\n setSelectedIds,\n search\n}: ${pascalSubmissionsName}TableProps<TValue>) {\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(10))\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(\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 } = ${hookName}(search)\n\n // Convert selectedIds array to rowSelection object format\n const rowSelection = React.useMemo(() => {\n const selection: Record<string, boolean> = {}\n const submissions = data?.submissions ?? []\n submissions.forEach((submission, index) => {\n if (selectedIds.includes(submission.id as number)) {\n selection[index.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.submissions])\n\n // Handle row selection changes\n const handleRowSelectionChange = React.useCallback(\n (\n updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)\n ) => {\n const submissions = data?.submissions ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n\n const newSelectedIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => submissions[Number.parseInt(key, 10)]?.id as number)\n .filter(Boolean)\n\n setSelectedIds(newSelectedIds)\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: {\n pageIndex,\n pageSize: effectivePageSize\n }\n }\n })\n\n return (\n <div className=\"space-y-4\">\n <div className=\"bg-card border overflow-hidden rounded-lg corner-squircle\">\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 ${label} Submissions...</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 submissions: {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 submissions found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* Pagination */}\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((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 <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\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setPageIndex(Math.max(0, pageIndex - 1))}\n disabled={!table.getCanPreviousPage()}\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setPageIndex(pageIndex + 1)}\n disabled={!table.getCanNextPage()}\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(adminPageDir, `${kebabName}-submissions-table.tsx`), content, 'utf-8')\n}\n\n/**\n * Generate submissions-page-content.tsx with page header and actions\n */\nasync function generatePageContentComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n pascalSubmissionName: string,\n _submissionName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const content = `'use client'\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Input\n} from '${ir.adminUi}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\nimport { deleteBulk${pascalSubmissionsName} } from '${ir.actions(`${kebabName}-form`)}'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Search, Settings, Trash2 } from 'lucide-react'\nimport Link from 'next/link'\nimport { parseAsArrayOf, parseAsInteger, parseAsString, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\nimport { toast } from 'sonner'\nimport { AdminPageHeader } from '@/components/admin'\nimport { ${pascalSubmissionsName}Table } from './${kebabName}-submissions-table'\n\nfunction 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\ninterface ${pascalSubmissionsName}PageContentProps<TValue> {\n columns: ColumnDef<${pascalSubmissionName}Data, TValue>[]\n}\n\nexport function ${pascalSubmissionsName}PageContent<TValue>({\n columns\n}: ${pascalSubmissionsName}PageContentProps<TValue>) {\n const queryClient = useQueryClient()\n const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n\n const searchAction = React.useCallback(\n async (formData: FormData) => {\n const value = formData.get('search') as string\n React.startTransition(() => {\n setSearch(value || null)\n })\n },\n [setSearch]\n )\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${pascalSubmissionsName}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} submission\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${kebabName}-submissions'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submissions')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n\n return (\n <>\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <AdminPageHeader title=\"${label}\" description=\"View and manage form submissions\" />\n <div className=\"flex items-center gap-2\">\n <form action={searchAction} className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"text-muted-foreground 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\"\n />\n </div>\n <SearchButton />\n </form>\n <Button variant=\"outline\" size=\"default\" asChild>\n <Link href=\"/admin/forms/${kebabName}/settings\">\n <Settings className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Settings\n </Link>\n </Button>\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} {selectedIds.length === 1 ? 'submission' : 'submissions'}\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 ? 'submission' : 'submissions'}.\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 </div>\n </div>\n\n <main className=\"space-y-4 p-5\">\n <${pascalSubmissionsName}Table\n columns={columns}\n selectedIds={selectedIds}\n setSelectedIds={setSelectedIds}\n search={search}\n />\n </main>\n </>\n )\n}\n`\n\n fs.writeFileSync(\n path.join(adminPageDir, `${kebabName}-submissions-page-content.tsx`),\n content,\n 'utf-8'\n )\n}\n\n/**\n * Generate view page for form submissions\n */\nasync function generateViewPage(\n adminPageDir: string,\n pascalSubmissionName: string,\n fields: FormField[],\n label: string,\n kebabName: string,\n includeDynamicFields: boolean\n): Promise<void> {\n const ir = getImportResolver()\n const viewPageDir = path.join(adminPageDir, '[id]/view')\n ensureDir(viewPageDir)\n\n // Check if any fields are upload/file type\n const hasUploadFields = fields.some((f) => f.type === 'upload' || f.type === 'file')\n\n // Generate field display items matching form field styling\n const fieldItems = fields\n .filter((f) => f.name) // Only fields with names\n .map((field) => {\n const fieldName = field.name || ''\n const fieldLabel = field.label\n\n // Handle different field types\n if (field.type === 'upload' || field.type === 'file') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm\">\n {submission.${fieldName} ? (\n <a\n href={submission.${fieldName}}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n download\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 hover:bg-secondary transition-colors\"\n >\n <Download className=\"size-4\" />\n Download File\n </a>\n ) : (\n <span className=\"text-muted-foreground\">No file uploaded</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'url') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? (\n <a\n href={submission.${fieldName}}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline break-all\"\n >\n {submission.${fieldName}}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'email') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? (\n <a\n href={\\`mailto:\\${submission.${fieldName}}\\`}\n className=\"text-primary hover:underline\"\n >\n {submission.${fieldName}}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'textarea') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 whitespace-pre-wrap min-h-[80px]\">\n {submission.${fieldName} || <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n }\n\n if (field.type === 'list') {\n if (field.fields && field.fields.length > 0) {\n // Object list\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm\">\n {submission.${fieldName} && Array.isArray(submission.${fieldName}) && submission.${fieldName}.length > 0 ? (\n <div className=\"space-y-2\">\n {submission.${fieldName}.map((item: Record<string, unknown>, idx: number) => (\n <div key={idx} className=\"p-3 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {Object.entries(item).map(([key, value]) => (\n <div key={key} className=\"flex gap-2\">\n <span className=\"font-medium capitalize\">{key}:</span>\n <span>{String(value)}</span>\n </div>\n ))}\n </div>\n ))}\n </div>\n ) : (\n <div className=\"px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 text-muted-foreground\">-</div>\n )}\n </div>\n </div>`\n }\n // Simple string list\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} && Array.isArray(submission.${fieldName}) && submission.${fieldName}.length > 0 ? (\n <ul className=\"list-disc list-inside\">\n {submission.${fieldName}.map((item: string, idx: number) => (\n <li key={idx}>{item}</li>\n ))}\n </ul>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'checkbox') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? 'Yes' : 'No'}\n </div>\n </div>`\n }\n\n if (field.type === 'date') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? new Date(submission.${fieldName}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n }\n\n // Default text display\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ?? <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n })\n .join('\\n')\n\n // Generate custom fields section for dynamic fields\n const customFieldsSection = includeDynamicFields\n ? `\n {/* Dynamic Fields (from CMS) */}\n {submission.customFields && Object.keys(submission.customFields).length > 0 && (\n <>\n <div className=\"border-t border-border my-4\" />\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-muted-foreground\">Custom Fields</p>\n </div>\n {Object.entries(submission.customFields).map(([key, value]) => (\n <div key={key} className=\"space-y-2\">\n <p className=\"text-sm font-medium capitalize\">{key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 whitespace-pre-wrap\">\n {value !== null && value !== undefined ? String(value) : <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>\n ))}\n </>\n )}`\n : ''\n\n const content = `import { Button } from '${ir.adminUi}'\nimport { get${pascalSubmissionName} } from '${ir.actions(`${kebabName}-form`)}'\nimport { ArrowLeft${hasUploadFields ? ', Download' : ''} } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n const submission = await get${pascalSubmissionName}(Number.parseInt(id, 10))\n\n if (!submission) {\n notFound()\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <AdminPageHeader title=\"${label} Submission\" description={\\`Viewing submission #\\${id}\\`} />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-5\">\n <div className=\"space-y-5 px-7 pt-7 pb-8 rounded-2xl corner-squircle border bg-background\">\n${fieldItems}${customFieldsSection}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Submitted At</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {new Date(submission.submittedAt).toLocaleString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n })}\n </div>\n </div>\n </div>\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(viewPageDir, 'page.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate settings page for form webhook configuration\n */\nasync function generateSettingsPage(\n adminPageDir: string,\n formName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const settingsPageDir = path.join(adminPageDir, 'settings')\n ensureDir(settingsPageDir)\n\n const content = `'use client'\n\nimport {\n Button,\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n Input,\n Switch,\n Textarea\n} from '${ir.adminUi}'\nimport { getFormSettings, testFormWebhook, upsertFormSettings } from '${ir.actions('form-settings')}'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { ArrowLeft, Send } from 'lucide-react'\nimport Link from 'next/link'\nimport * as React from 'react'\nimport { useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\n\nconst formSchema = z.object({\n notificationEmails: z.string().optional(),\n webhookUrl: z.string().url('Please enter a valid URL').or(z.literal('')),\n webhookEnabled: z.boolean()\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\nexport default function SettingsPage() {\n const [isPending, startTransition] = React.useTransition()\n const [isTestingWebhook, setIsTestingWebhook] = React.useState(false)\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n notificationEmails: '',\n webhookUrl: '',\n webhookEnabled: false\n }\n })\n\n // Load existing settings on mount\n React.useEffect(() => {\n const loadSettings = async () => {\n const settings = await getFormSettings('${formName}')\n if (settings) {\n form.reset({\n notificationEmails: settings.notificationEmails || '',\n webhookUrl: settings.webhookUrl || '',\n webhookEnabled: settings.webhookEnabled\n })\n }\n }\n loadSettings()\n }, [form])\n\n const onSubmit = (values: FormValues) => {\n startTransition(async () => {\n try {\n const result = await upsertFormSettings('${formName}', {\n notificationEmails: values.notificationEmails || null,\n webhookUrl: values.webhookUrl || null,\n webhookEnabled: values.webhookEnabled\n })\n\n if (result.success) {\n toast.success('Settings saved successfully')\n } else {\n toast.error(result.error || 'Failed to save settings')\n }\n } catch (error) {\n console.error('Error saving settings:', error)\n toast.error('An error occurred while saving settings')\n }\n })\n }\n\n const handleTestWebhook = async () => {\n const webhookUrl = form.getValues('webhookUrl')\n if (!webhookUrl) {\n toast.error('Please enter a webhook URL first')\n return\n }\n\n setIsTestingWebhook(true)\n try {\n // Save the URL first\n await upsertFormSettings('${formName}', {\n webhookUrl: webhookUrl || null\n })\n\n const result = await testFormWebhook('${formName}')\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 } catch (error) {\n console.error('Error testing webhook:', error)\n toast.error('An error occurred while testing the webhook')\n } finally {\n setIsTestingWebhook(false)\n }\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"outline\" size=\"icon\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">\n <ArrowLeft className=\"size-4\" />\n </Link>\n </Button>\n <AdminPageHeader\n title=\"${label} Settings\"\n description=\"Configure webhook and notification settings\"\n />\n </div>\n </div>\n </div>\n\n <main className=\"container mx-auto max-w-5xl p-5\">\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <div className=\"space-y-6 px-7 pt-7 pb-8 rounded-2xl corner-squircle border bg-background\">\n <FormField\n control={form.control}\n name=\"notificationEmails\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Notification Emails</FormLabel>\n <FormControl>\n <Textarea\n placeholder=\"email1@example.com, email2@example.com\"\n className=\"min-h-[80px]\"\n {...field}\n />\n </FormControl>\n <FormDescription>\n Email addresses to receive notifications when form is submitted (comma-separated). Falls back to NOTIFICATION_EMAIL env var if empty.\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"webhookUrl\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Webhook URL</FormLabel>\n <FormControl>\n <Input\n type=\"url\"\n placeholder=\"https://hooks.zapier.com/hooks/catch/...\"\n {...field}\n />\n </FormControl>\n <FormDescription>\n POST request will be sent to this URL when a form is submitted\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"webhookEnabled\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div className=\"space-y-0.5\">\n <FormLabel className=\"text-base\">Enable Webhook</FormLabel>\n <FormDescription>\n Send form submission data to the webhook URL\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n checked={field.value}\n onCheckedChange={field.onChange}\n />\n </FormControl>\n </FormItem>\n )}\n />\n\n <div className=\"pt-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleTestWebhook}\n disabled={isTestingWebhook || !form.watch('webhookUrl')}\n >\n <Send className=\"mr-2 h-4 w-4\" />\n {isTestingWebhook ? 'Sending...' : 'Test Webhook'}\n </Button>\n </div>\n </div>\n\n <div className=\"fixed bottom-0 left-0 md:left-[calc(var(--sidebar-width))] right-0 border-t bg-background px-6 py-4\">\n <div className=\"container mx-auto max-w-5xl flex justify-end gap-2\">\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">Cancel</Link>\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Saving...' : 'Save Settings'}\n </Button>\n </div>\n </div>\n </form>\n </Form>\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(settingsPageDir, 'page.tsx'), content, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n toCamelCase,\n toPascalCase,\n toSnakeCase\n} from '../utils'\nimport { generateEmailTemplate } from './email-template'\nimport { generateFormAdminPages } from './form-admin-pages'\nimport { updateFormNavigation } from './form-navigation'\n\n/**\n * Check if a form schema has dynamicFields\n * Dynamic fields are stored in customFields JSON column\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Convert showWhen object to condition string\n * showWhen: { field: \"status\", value: \"active\" } -> \"status === 'active'\"\n * showWhen: { field: \"status\", value: [\"active\", \"pending\"] } -> \"['active', 'pending'].includes(status)\"\n */\nfunction showWhenToCondition(showWhen: {\n field: string\n value: boolean | string | number | (string | number)[]\n}): string {\n const { field, value } = showWhen\n if (Array.isArray(value)) {\n const values = value.map((v) => (typeof v === 'string' ? `'${v}'` : v)).join(', ')\n return `[${values}].includes(${field})`\n }\n if (typeof value === 'boolean') {\n return value ? `${field} === true` : `${field} !== true`\n }\n if (typeof value === 'string') {\n return `${field} === '${value}'`\n }\n return `${field} === ${value}`\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n * Propagates group conditions to child fields\n * Skips dynamicFields since they have no database columns (rendered from CMS)\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[], parentCondition?: string): FormField[] => {\n return fields.flatMap((field) => {\n // Skip dynamicFields - they don't have database columns (rendered from CMS)\n if (field.type === 'dynamicFields') {\n return []\n }\n\n // Convert showWhen to condition if present (and field doesn't have explicit condition)\n let fieldCondition = field.condition\n if (!fieldCondition && field.showWhen) {\n fieldCondition = showWhenToCondition(field.showWhen)\n }\n\n if (field.type === 'group' && field.fields) {\n // Combine parent condition with group condition\n const combinedCondition =\n parentCondition && fieldCondition\n ? `(${parentCondition}) && (${fieldCondition})`\n : parentCondition || fieldCondition\n // Recursively flatten group fields with inherited condition\n return flattenFields(field.fields, combinedCondition)\n }\n // For non-group fields, inherit the parent condition if field doesn't have its own\n if (parentCondition && !fieldCondition) {\n return [{ ...field, condition: parentCondition }]\n }\n // If field has its own condition and there's a parent condition, combine them\n if (parentCondition && fieldCondition) {\n return [{ ...field, condition: `(${parentCondition}) && (${fieldCondition})` }]\n }\n // If field has its own condition (from showWhen conversion), use it\n if (fieldCondition && !field.condition) {\n return [{ ...field, condition: fieldCondition }]\n }\n return field.type === 'group' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Generate email field HTML from schema fields, including dynamicFields inline\n * This iterates through the original schema fields to preserve ordering\n * and inserts customFields HTML at the position where dynamicFields appears\n */\nfunction _generateEmailFieldsHtml(schema: FormSchema): string {\n const processFields = (fields: FormField[]): string[] => {\n const htmlParts: string[] = []\n for (const field of fields) {\n if (field.type === 'dynamicFields') {\n // Insert dynamic/custom fields at this position\n htmlParts.push(`\\${data.customFields && Object.keys(data.customFields).length > 0\n ? Object.entries(data.customFields).map(([key, value]) => \\`\n <div style=\"margin-bottom: 16px;\">\n <p style=\"color: #666; font-size: 14px; font-weight: 600; margin: 0 0 4px 0;\">\\${key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <p style=\"color: #333; font-size: 16px; margin: 0;\">\\${formatValue(value, 'text')}</p>\n </div>\n \\`).join('')\n : ''}`)\n } else if (field.type === 'group' && field.fields) {\n // Recursively process group fields\n htmlParts.push(...processFields(field.fields))\n } else if (field.name && field.label) {\n // Regular field\n htmlParts.push(`<div style=\"margin-bottom: 16px;\">\n <p style=\"color: #666; font-size: 14px; font-weight: 600; margin: 0 0 4px 0;\">${field.label}</p>\n <p style=\"color: #333; font-size: 16px; margin: 0;\">\\${formatValue(data.${field.name}, '${field.type}')}</p>\n </div>`)\n }\n }\n return htmlParts\n }\n\n const allFields =\n schema.fields || (schema.steps ? schema.steps.flatMap((step) => step.fields) : [])\n return processFields(allFields).join('\\n ')\n}\n\n/**\n * Generate props for the React Email component render call\n */\nfunction generateEmailPropsForRender(fields: FormField[], includeDynamicFields: boolean): string {\n const fieldProps = fields\n .filter((f) => f.name) // Only include fields with names\n .map((f) => `${f.name}: data.${f.name} ?? null,`)\n .join('\\n ')\n\n const customFieldsProp = includeDynamicFields\n ? '\\n customFields: data.customFields ?? null,'\n : ''\n\n return fieldProps + customFieldsProp\n}\n\n/**\n * Generate the name expression for email subject based on available fields\n */\nfunction getEmailSubjectNameExpr(fields: FormField[]): string {\n const fieldNames = fields.map((f) => f.name)\n const hasName = fieldNames.includes('name')\n const hasFirstName = fieldNames.includes('firstName')\n const hasLastName = fieldNames.includes('lastName')\n const hasEmail = fieldNames.includes('email')\n\n if (hasName) {\n return hasEmail ? \"data.name || data.email || 'Unknown'\" : \"data.name || 'Unknown'\"\n }\n if (hasFirstName && hasLastName) {\n const nameExpr = '`$' + '{data.firstName || \"\"} $' + '{data.lastName || \"\"}`.trim()'\n return hasEmail ? `(${nameExpr}) || data.email || 'Unknown'` : `(${nameExpr}) || 'Unknown'`\n }\n if (hasFirstName) {\n return hasEmail ? \"data.firstName || data.email || 'Unknown'\" : \"data.firstName || 'Unknown'\"\n }\n if (hasEmail) {\n return \"data.email || 'Unknown'\"\n }\n return \"'Unknown'\"\n}\n\n/**\n * Generate webhook code for a form\n * Handles custom payloads for specific forms (e.g., application form with price lookup)\n * Includes customFields expansion for forms with dynamicFields\n */\nfunction generateWebhookCode(\n formName: string,\n fields: FormField[],\n includeDynamicFields: boolean\n): string {\n // Application form has a custom payload with price lookup\n if (formName === 'application') {\n return `// Send webhook (fire-and-forget, non-blocking)\n // Custom payload for Zapier integration with price lookup\n ;(async () => {\n try {\n const settings = await getFormSettings('application')\n if (settings?.webhookEnabled && settings?.webhookUrl) {\n // Look up price from course tiers\n let price = ''\n if (data.course && data.bootcampTier) {\n const { courses } = await getCourses({ title: data.course })\n if (courses[0]) {\n const tier = courses[0].tiers?.find((t) => t.name === data.bootcampTier)\n if (tier) {\n const feeStr =\n data.preferredPaymentSchedule === 'monthly' ? tier.monthlyFee : tier.upfrontFee\n price = feeStr?.replace(/[$,]/g, '') || ''\n }\n }\n }\n\n // Expand customFields into individual webhook fields\n const customFieldsExpanded: Record<string, unknown> = {}\n if (data.customFields && typeof data.customFields === 'object') {\n for (const [key, value] of Object.entries(data.customFields)) {\n customFieldsExpanded[key] = value ?? ''\n }\n }\n\n sendWebhook(settings.webhookUrl, {\n bootcamp: data.course ?? '',\n first_name: data.firstName ?? '',\n last_name: data.lastName ?? '',\n email: data.email ?? '',\n linkedin_url: data.linkedin ?? '',\n employment_history: data.employmentHistory ?? '',\n education_history: data.isSelfTaught ?? '',\n why_take_this_bootcamp: data.whyDoYouWantToEnroll ?? '',\n price,\n payment_method: data.preferredPaymentMethod ?? '',\n marketing_source: data.howDidYouHearAboutUs ?? '',\n ...customFieldsExpanded\n })\n }\n } catch (error) {\n console.error('Failed to send webhook:', error)\n }\n })()`\n }\n\n // Default webhook payload for other forms\n const fieldMappings = fields\n .map((f) => `${toSnakeCase(f.name!)}: data.${f.name} ?? ''`)\n .join(',\\n ')\n\n // Add customFields expansion if form has dynamic fields\n const customFieldsCode = includeDynamicFields\n ? `\n // Expand customFields into individual webhook fields\n const customFieldsExpanded: Record<string, unknown> = {}\n if (data.customFields && typeof data.customFields === 'object') {\n for (const [key, value] of Object.entries(data.customFields)) {\n customFieldsExpanded[key] = value ?? ''\n }\n }\n`\n : ''\n\n const customFieldsSpread = includeDynamicFields ? ',\\n ...customFieldsExpanded' : ''\n\n return `// Send webhook (fire-and-forget, non-blocking)\n ;(async () => {\n try {\n const settings = await getFormSettings('${formName}')\n if (settings?.webhookEnabled && settings?.webhookUrl) {${customFieldsCode}\n sendWebhook(settings.webhookUrl, {\n form_name: '${formName}',\n submission_id: submission.id,\n submitted_at: submission.submittedAt,\n ${fieldMappings}${customFieldsSpread}\n })\n }\n } catch (error) {\n console.error('Failed to send webhook:', error)\n }\n })()`\n}\n\n/**\n * Generate Mailchimp audience subscription code for a form\n * Auto-detects the email field unless explicitly specified in schema\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 `// Add to Mailchimp audience (fire-and-forget, non-blocking)\n addToMailchimpAudience(data.${emailFieldName})`\n}\n\n/**\n * Check if schema is multi-step\n */\nfunction _isMultiStep(schema: FormSchema): boolean {\n return !!schema.steps && schema.steps.length > 0\n}\n\n/**\n * Map form field type to Drizzle type\n */\nfunction getDrizzleTypeForFormField(field: FormField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'text':\n if (field.maxLength) {\n requiredImports.add('varchar')\n return `varchar({ length: ${field.maxLength} })`\n }\n requiredImports.add('varchar')\n return 'varchar({ length: 255 })'\n case 'textarea':\n requiredImports.add('text')\n return 'text()'\n case 'email':\n requiredImports.add('varchar')\n return 'varchar({ length: 255 })'\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: 255 })'\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 // Check if list has nested fields (object array) or simple strings\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/**\n * Map form field type to Zod validation\n * @param field - The form field definition\n * @param options - Options for generating the zod type\n * @param options.treatAsOptional - If true, generate optional schema even if field.required is true\n * This is used for conditional required fields which are validated in superRefine\n */\nfunction getZodTypeForFormField(\n field: FormField,\n options: { treatAsOptional?: boolean } = {}\n): string {\n const label = field.label\n // For conditional required fields, treat as optional in base schema\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 if (field.maxLength)\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n if (field.pattern)\n zodType += `.regex(new RegExp('${field.pattern}'), 'Invalid ${label} format')`\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 if (field.maxLength)\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\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 if (field.max !== undefined)\n zodType += `.max(${field.max}, '${label} must be at most ${field.max}')`\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 'timezone':\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} must be accepted' })`\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 'group':\n // Group fields are nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((f) => ` ${f.name}: ${getZodTypeForFormField(f)}`)\n .join(',\\n')\n return isRequired\n ? `z.object({\\n${nestedFields}\\n })`\n : `z.object({\\n${nestedFields}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n case 'list':\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n // Generate object schema for nested fields\n const nestedFields = field.fields\n .map((f) => ` ${f.name}: ${getZodTypeForFormField(f)}`)\n .join(',\\n')\n return isRequired\n ? `z.array(z.object({\\n${nestedFields}\\n })).min(1, '${label} is required')`\n : `z.array(z.object({\\n${nestedFields}\\n })).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\n ? `z.string().min(1, 'Please upload a file for ${label}')`\n : 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n default:\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Generate database schema for form submissions\n */\nexport async function generateFormDatabase(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const tableName = `${toCamelCase(schema.name)}Submissions`\n const fields = getAllFields(schema)\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Track required Drizzle imports\n const requiredImports = new Set<string>(['serial', 'timestamp', 'text'])\n\n // Add jsonb import if form has dynamic fields\n if (includeDynamicFields) {\n requiredImports.add('jsonb')\n }\n\n // Generate field definitions\n const fieldDefinitions = fields\n .map((field) => {\n const drizzleType = getDrizzleTypeForFormField(field, requiredImports)\n const nullable = field.required ? '' : ''\n return ` ${field.name}: ${drizzleType}${nullable},`\n })\n .join('\\n')\n\n // Add customFields column if form has dynamic fields\n const customFieldsColumn = includeDynamicFields\n ? '\\n customFields: jsonb().$type<Record<string, unknown>>(),'\n : ''\n\n // Generate the table schema\n const tableSchema = `\nexport const ${tableName} = pgTable('${toPascalCase(schema.name)}Submissions', {\n id: serial().primaryKey().notNull(),\n${fieldDefinitions}${customFieldsColumn}\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 // Read existing schema file\n const schemaPath = path.join(paths.database, 'src/schema.ts')\n let schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n\n // Add required imports if not present\n const importLine = Array.from(requiredImports).sort().join(', ')\n if (!schemaContent.includes(`import { ${importLine}`)) {\n // Update the imports\n const drizzleImportRegex = /import\\s+{([^}]+)}\\s+from\\s+'drizzle-orm\\/pg-core'/\n const match = schemaContent.match(drizzleImportRegex)\n if (match) {\n const existingImports = match[1].split(',').map((i) => i.trim())\n const allImports = Array.from(new Set([...existingImports, ...Array.from(requiredImports)]))\n .sort()\n .join(', ')\n schemaContent = schemaContent.replace(\n drizzleImportRegex,\n `import { ${allImports} } from 'drizzle-orm/pg-core'`\n )\n }\n }\n\n // Check if table already exists\n if (schemaContent.includes(`export const ${tableName}`)) {\n if (!options.force) {\n console.warn(`⚠️ Table ${tableName} already exists. Use --force to overwrite.`)\n return schemaPath\n }\n // Remove existing table definition - match the full table definition including closing parenthesis\n const tableRegex = new RegExp(\n `export const ${tableName} = pgTable\\\\([\\\\s\\\\S]*?\\\\n\\\\}\\\\)\\\\n`,\n 'g'\n )\n schemaContent = schemaContent.replace(tableRegex, '')\n console.log(` ℹ️ Removed existing ${tableName} table definition`)\n }\n\n // Append new table schema\n schemaContent += `\\n${tableSchema}`\n\n // Write updated schema\n fs.writeFileSync(schemaPath, schemaContent, 'utf-8')\n\n console.log(` ✓ Database schema updated: ${schemaPath}`)\n return schemaPath\n}\n\n/**\n * Generate server actions for form submissions\n */\nexport async function generateFormActions(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const tableName = `${toCamelCase(formName)}Submissions`\n const pascalName = toPascalCase(formName)\n const fields = getAllFields(schema)\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Generate TypeScript interface for submission data\n // Conditional required fields are treated as optional (they may not be present when condition is not met)\n const dataInterfaceFields = fields\n .map((field) => {\n let tsType: string\n if (field.type === 'number') {\n tsType = 'number'\n } else if (field.type === 'checkbox') {\n tsType = 'boolean'\n } else if (field.type === 'multiselect') {\n tsType = 'string[]'\n } else if (field.type === 'list') {\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n tsType = 'Record<string, unknown>[]'\n } else {\n tsType = 'string[]'\n }\n } else {\n tsType = 'string'\n }\n // Conditional required fields are effectively optional\n const isEffectivelyRequired = field.required && !field.condition\n const optional = isEffectivelyRequired ? '' : ' | null'\n return ` ${field.name}${isEffectivelyRequired ? '' : '?'}: ${tsType}${optional}`\n })\n .join('\\n')\n\n // Add customFields if form has dynamic fields\n const customFieldsLine = includeDynamicFields\n ? '\\n customFields?: Record<string, unknown> | null'\n : ''\n const dataInterface = dataInterfaceFields + customFieldsLine\n\n const actionContent = `'use server'\n\nimport { ${tableName}, db } from '${ir.database}'\nimport { desc, eq, or } from 'drizzle-orm'\n${schema.notificationEmail ? \"import { render } from '@react-email/components'\" : ''}\n${schema.notificationEmail ? \"import { Resend } from 'resend'\" : ''}\nimport { sendWebhook } from '../utils/webhook'\n${schema.mailchimp ? \"import { addToMailchimpAudience } from '../utils/mailchimp'\" : ''}\n${formName === 'application' ? \"import { getCourses } from './courses'\" : ''}\nimport { getFormSettings } from './form-settings'\n${schema.notificationEmail ? `import { ${pascalName}SubmissionEmail } from '@/emails/${formName}-submission'` : ''}\n\n${schema.notificationEmail ? `const resend = new Resend(process.env.RESEND_API_KEY)\\n` : ''}\nexport interface ${pascalName}SubmissionData {\n id: number\n${dataInterface}\n ipAddress: string | null\n userAgent: string | null\n submittedAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface ${pascalName}SubmissionsResponse {\n submissions: ${pascalName}SubmissionData[]\n total: number\n}\n\nexport interface Create${pascalName}SubmissionInput {\n${dataInterface}\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Update${pascalName}SubmissionInput {\n id: number\n${dataInterface}\n}\n\nexport interface Create${pascalName}SubmissionResult {\n success: boolean\n error?: string\n submission?: ${pascalName}SubmissionData\n}\n\nexport interface Delete${pascalName}SubmissionResult {\n success: boolean\n error?: string\n count?: number\n}\n\nexport async function get${pascalName}Submissions(): Promise<${pascalName}SubmissionsResponse> {\n try {\n const submissions = await db.select().from(${tableName}).orderBy(desc(${tableName}.submittedAt))\n const total = submissions.length\n\n return {\n submissions: submissions as ${pascalName}SubmissionData[],\n total\n }\n } catch (error) {\n console.error('Error fetching ${formName} submissions:', error)\n throw new Error('Failed to fetch ${formName} submissions')\n }\n}\n\nexport async function get${pascalName}Submission(id: number): Promise<${pascalName}SubmissionData | null> {\n try {\n const [submission] = await db\n .select()\n .from(${tableName})\n .where(eq(${tableName}.id, id))\n .limit(1)\n\n return submission as ${pascalName}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\nexport async function create${pascalName}Submission(\n data: Create${pascalName}SubmissionInput\n): Promise<Create${pascalName}SubmissionResult> {\n try {\n // Validate data (basic server-side validation)\n // Unconditional required fields\n ${fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) => `if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }`\n )\n .join('\\n ')}\n // Conditional required fields - only validate when condition is met\n ${fields\n .filter((f) => f.required && f.condition)\n .map((f) => {\n // Convert condition to use data. prefix for field references\n const serverCondition = f.condition!.replace(/(\\w+)\\s*(===|!==|==|!=)/g, 'data.$1 $2')\n return `if (${serverCondition}) {\n if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }\n }`\n })\n .join('\\n ')}\n\n // Save to database (MUST succeed for success response)\n const [submission] = await db\n .insert(${tableName})\n .values({\n ...data,\n submittedAt: new Date().toISOString()\n })\n .returning()\n\n ${\n schema.notificationEmail\n ? `// Send email notification (fire-and-forget pattern)\n // IMPORTANT: Email failures don't affect the response to client\n // If DB save succeeded, client gets success = true\n if (process.env.RESEND_API_KEY) {\n // Email sending wrapped in try-catch to prevent throwing\n try {\n // Get notification emails from form settings (primary), fall back to env var (backup)\n const settings = await getFormSettings('${formName}')\n const notificationEmails = settings?.notificationEmails\n ? settings.notificationEmails.split(',').map((e) => e.trim()).filter(Boolean)\n : process.env.NOTIFICATION_EMAIL\n ? [process.env.NOTIFICATION_EMAIL]\n : []\n\n if (notificationEmails.length === 0) {\n console.warn('No notification emails configured for ${formName} form')\n } else {\n // Render the React Email template\n const emailHtml = await render(\n ${pascalName}SubmissionEmail({\n ${generateEmailPropsForRender(fields, includeDynamicFields)}\n submittedAt: submission.submittedAt\n })\n )\n\n await resend.emails.send({\n from: process.env.FROM_EMAIL || 'noreply@betterstart.io',\n to: notificationEmails,\n subject: \\`New ${schema.label}: \\${${getEmailSubjectNameExpr(fields)}} (#\\${submission.id})\\`,\n html: emailHtml\n })\n }\n } catch (error) {\n // Log error but DON'T throw - submission already succeeded\n console.error('Failed to send notification email:', error)\n // Optionally: Store failed email in a queue for retry\n }\n }`\n : ''\n }\n\n ${generateWebhookCode(formName, fields, includeDynamicFields)}\n\n ${generateMailchimpCode(schema, fields)}\n\n return {\n success: true,\n submission: submission as ${pascalName}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\nexport async function update${pascalName}Submission(\n id: number,\n data: Create${pascalName}SubmissionInput | Update${pascalName}SubmissionInput\n): Promise<Create${pascalName}SubmissionResult> {\n try {\n // Validate data (basic server-side validation)\n // Unconditional required fields\n ${fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) => `if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }`\n )\n .join('\\n ')}\n // Conditional required fields - only validate when condition is met\n ${fields\n .filter((f) => f.required && f.condition)\n .map((f) => {\n // Convert condition to use data. prefix for field references\n const serverCondition = f.condition!.replace(/(\\w+)\\s*(===|!==|==|!=)/g, 'data.$1 $2')\n return `if (${serverCondition}) {\n if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }\n }`\n })\n .join('\\n ')}\n\n // Update in database\n const [submission] = await db\n .update(${tableName})\n .set({\n ...data,\n updatedAt: new Date().toISOString()\n })\n .where(eq(${tableName}.id, id))\n .returning()\n\n if (!submission) {\n return { success: false, error: 'Submission not found' }\n }\n\n return {\n success: true,\n submission: submission as ${pascalName}SubmissionData\n }\n } catch (error) {\n console.error(\\`Error updating ${formName} submission \\${id}:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update ${formName} submission'\n }\n }\n}\n\nexport async function delete${pascalName}Submission(id: number): Promise<Delete${pascalName}SubmissionResult> {\n try {\n await db.delete(${tableName}).where(eq(${tableName}.id, id))\n\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\nexport async function deleteBulk${pascalName}Submissions(ids: number[]): Promise<Delete${pascalName}SubmissionResult> {\n try {\n if (ids.length === 0) {\n return { success: true, count: 0 }\n }\n\n await db.delete(${tableName}).where(\n or(...ids.map(id => eq(${tableName}.id, id)))\n )\n\n return { \n success: true,\n count: ids.length\n }\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// Export functions for CSV/JSON\nexport async function export${pascalName}SubmissionsCSV(): Promise<string> {\n const { submissions } = await get${pascalName}Submissions()\n \n if (submissions.length === 0) {\n return ''\n }\n\n // Generate CSV header\n const headers = Object.keys(submissions[0]).join(',')\n \n // Generate CSV rows\n const rows = submissions.map((sub) =>\n Object.values(sub)\n .map((val) => {\n if (val === null || val === undefined) return ''\n const str = String(val)\n // Escape quotes and wrap in quotes if contains comma, quote, or newline\n if (str.includes(',') || str.includes('\"') || str.includes('\\\\n')) {\n return \\`\"\\${str.replace(/\"/g, '\"\"')}\"\\`\n }\n return str\n })\n .join(',')\n )\n\n return [headers, ...rows].join('\\\\n')\n}\n\nexport async function export${pascalName}SubmissionsJSON(): Promise<string> {\n const { submissions } = await get${pascalName}Submissions()\n return JSON.stringify(submissions, null, 2)\n}\n`\n\n // Write actions file\n const actionsPath = path.join(paths.lib, 'src/actions', `${formName}-form.ts`)\n const actionsDir = path.dirname(actionsPath)\n ensureDir(actionsDir)\n\n if (fs.existsSync(actionsPath) && !options.force) {\n console.warn(`⚠️ Actions file already exists: ${actionsPath}. Use --force to overwrite.`)\n return actionsPath\n }\n\n fs.writeFileSync(actionsPath, actionContent, 'utf-8')\n console.log(` ✓ Actions generated: ${actionsPath}`)\n\n // Update index.ts to export new actions\n const indexPath = path.join(actionsDir, 'index.ts')\n const exportLine = `export * from './${formName}-form'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n console.log(` ✓ Updated actions/index.ts`)\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n console.log(` ✓ Created actions/index.ts`)\n }\n\n return actionsPath\n}\n\n/**\n * Generate React Query hook for form submissions\n */\nexport async function generateFormHook(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const camelName = toCamelCase(formName)\n\n const hookContent = `import {\n create${pascalName}Submission,\n delete${pascalName}Submission,\n export${pascalName}SubmissionsCSV,\n export${pascalName}SubmissionsJSON,\n get${pascalName}Submission,\n get${pascalName}Submissions,\n update${pascalName}Submission\n} from '${ir.actions(`${formName}-form`)}'\nimport type { Create${pascalName}SubmissionInput } from '${ir.actions(`${formName}-form`)}'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useRouter } from 'next/navigation'\nimport { toast } from 'sonner'\n\nexport function use${pascalName}Submissions(search?: string) {\n return useQuery({\n queryKey: ['${camelName}-submissions', search ?? ''],\n queryFn: () => get${pascalName}Submissions()\n })\n}\n\nexport function use${pascalName}Submission(id: number | null) {\n return useQuery({\n queryKey: ['${camelName}-submission', id],\n queryFn: () => get${pascalName}Submission(id!),\n enabled: !!id\n })\n}\n\nexport function useCreate${pascalName}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (data: Create${pascalName}SubmissionInput) => create${pascalName}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${(schema.successMessage || 'Form submitted successfully').replace(\n /'/g,\n \"\\\\'\"\n )}')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-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 useUpdate${pascalName}Submission() {\n const queryClient = useQueryClient()\n const router = useRouter()\n\n return useMutation({\n mutationFn: ({ id, data }: { id: number; data: Create${pascalName}SubmissionInput }) => update${pascalName}Submission(id, data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('Submission updated successfully')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submissions'] })\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submission'] })\n router.push('/admin/forms/${formName}')\n } else {\n toast.error(result.error || 'Failed to update submission')\n }\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update submission')\n }\n })\n}\n\nexport function useDelete${pascalName}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: number) => delete${pascalName}Submission(id),\n onSuccess: async () => {\n toast.success('Submission deleted successfully')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submissions'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to delete submission')\n }\n })\n}\n\nexport function useExport${pascalName}SubmissionsCSV() {\n return useMutation({\n mutationFn: export${pascalName}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${pascalName}SubmissionsJSON() {\n return useMutation({\n mutationFn: export${pascalName}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 const hookPath = path.join(paths.hooks, 'src', `use-${formName}-form.ts`)\n const hooksDir = path.dirname(hookPath)\n ensureDir(hooksDir)\n\n if (fs.existsSync(hookPath) && !options.force) {\n console.warn(`⚠️ Hook already exists: ${hookPath}. Use --force to overwrite.`)\n return hookPath\n }\n\n fs.writeFileSync(hookPath, hookContent, 'utf-8')\n console.log(` ✓ Hook generated: ${hookPath}`)\n\n // Update index.ts to export new hook\n const indexPath = path.join(hooksDir, 'index.ts')\n const exportLine = `export * from './use-${formName}-form'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n console.log(` ✓ Updated hooks/index.ts`)\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n console.log(` ✓ Created hooks/index.ts`)\n }\n\n return hookPath\n}\n\n/**\n * Generate form field JSX\n */\nfunction generateFormFieldJSX(\n field: FormField,\n options: { useCourseColors?: boolean } = {}\n): string {\n const fieldName = field.name || ''\n const label = field.label\n const placeholder = field.placeholder || ''\n const hint = field.hint || ''\n const { useCourseColors = false } = options\n\n // Handle hidden fields - they don't render but are in the form\n if (field.hidden) {\n return ` <input type=\"hidden\" {...form.register(\"${fieldName}\")} />`\n }\n\n // Extract field dependencies from condition (e.g., \"appliedBefore === 'no'\" -> [\"appliedBefore\"])\n const getWatchFields = (condition?: string): string[] => {\n if (!condition) return []\n const fieldNamePattern = /\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g\n const matches = condition.matchAll(fieldNamePattern)\n const fields = Array.from(matches, (m) => m[1]).filter(\n (f) => !['true', 'false', 'null', 'undefined'].includes(f)\n )\n return [...new Set(fields)] // Remove duplicates\n }\n\n // Generate the actual field JSX (inner content)\n const generateFieldContent = (): string => {\n // Handle relationship fields (dynamic options from database)\n if (field.relationship && field.relationshipField && field.nuqsQueryParam) {\n const relationshipField = field.relationshipField\n\n // Generate options variable name (e.g., tierOptions)\n const optionsVarName = `${relationshipField}Options`\n\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"space-y-2\">\n <FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n ${\n hint\n ? `<FormDescription dangerouslySetInnerHTML={{ __html: renderMarkdownInline(\"${hint.replace(\n /\"/g,\n '\\\\\"'\n )}\") }} />`\n : ''\n }\n <FormControl>\n {${optionsVarName}.length > 0 ? (\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n {${optionsVarName}.map((option) => (\n <div \n key={option.value} \n className=\"flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5\" \n data-state={field.value === option.value ? \"checked\" : \"unchecked\"}\n style={{\n borderColor: field.value === option.value \n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)',\n backgroundColor: field.value === option.value\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem \n value={option.value} \n id={\\`${fieldName}-\\${option.value}\\`}\n style={{\n borderColor: field.value === option.value \n ? courseColor\n : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor={\\`${fieldName}-\\${option.value}\\`}>{option.label}</Label>\n </div>\n ))}\n </RadioGroup>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n Please select a course first\n </p>\n )}\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n }\n\n // Handle group type - render nested fields in a grid\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields\n .map((nestedField) => generateFormFieldJSX(nestedField, options))\n .join('\\n\\n')\n\n // Only show heading if label is set\n const headingJSX = label\n ? ` <h3 className=\"text-lg font-medium\">${label}</h3>`\n : ''\n\n // Generate the group content\n const groupContent = ` <div className=\"space-y-8\">\n${headingJSX}\n <div className=\"grid ${gridClass} gap-8\">\n${groupFields}\n </div>\n </div>`\n\n // Check for group-level showWhen condition\n if (field.showWhen) {\n const showWhenCondition = showWhenToCondition(field.showWhen)\n const watchFields = getWatchFields(showWhenCondition)\n\n // Split condition by string literals to avoid replacing inside them\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = showWhenCondition\n let match: RegExpExecArray | null\n\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n // Replace field names with watched variable names (e.g., fieldName -> fieldNameValue)\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (m) => {\n if (['true', 'false', 'null', 'undefined'].includes(m)) {\n return m\n }\n if (watchFields.includes(m)) {\n return `${m}Value`\n }\n return m\n })\n })\n\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` {${conditionCheck} && (\n${groupContent}\n )}`\n }\n\n return groupContent\n }\n\n switch (field.type) {\n case 'textarea':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Textarea placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'email':\n case 'phone':\n case 'url':\n case 'text':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input type=\"${\n field.type === 'email'\n ? 'email'\n : field.type === 'phone'\n ? 'tel'\n : field.type === 'url'\n ? 'url'\n : 'text'\n }\" placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'number':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input type=\"number\" placeholder=\"${placeholder}\" {...field} onChange={(e) => field.onChange(e.target.valueAsNumber)} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'date':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input\n type=\"date\"\n {...field}\n value={field.value || ''}\n />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'checkbox':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value}\n onCheckedChange={field.onChange}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel${hint ? ' className=\"leading-snug\"' : ''}>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n ${\n hint\n ? `<FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />`\n : ''\n }\n </div>\n \n </FormItem>\n )}\n />`\n\n case 'select':\n if (!field.options || field.options.length === 0) {\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n }\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field, fieldState }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n \n <FormControl>\n <Select onValueChange={field.onChange} value={field.value}>\n <SelectTrigger aria-invalid={fieldState.error ? \"true\" : \"false\"}>\n <SelectValue placeholder=\"${placeholder || 'Please select'}\" />\n </SelectTrigger>\n <SelectContent>\n ${field.options\n .map(\n (opt) => `<SelectItem value=\"${opt.value}\">${opt.label}</SelectItem>`\n )\n .join('\\n ')}\n </SelectContent>\n </Select>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'radio':\n if (!field.options || field.options.length === 0) {\n return ` <div>Radio field requires options</div>`\n }\n\n // Use course colors only for application form\n if (useCourseColors) {\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"${hint ? 'space-y-3' : 'space-y-2'}\">\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n\n <FormControl>\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n ${field.options\n .map(\n (opt) => `<div \n className=\"flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5\" \n data-state={field.value === \"${opt.value}\" ? \"checked\" : \"unchecked\"}\n style={{\n borderColor: field.value === \"${opt.value}\"\n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)',\n backgroundColor: field.value === \"${opt.value}\"\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem \n value=\"${opt.value}\" \n id=\"${fieldName}-${opt.value}\"\n style={{\n borderColor: field.value === \"${opt.value}\"\n ? courseColor\n : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor=\"${fieldName}-${opt.value}\">${opt.label}</Label>\n </div>`\n )\n .join('\\n ')}\n </RadioGroup>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n }\n\n // Standard styling for other forms\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"${hint ? 'space-y-3' : 'space-y-2'}\">\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n ${field.options\n .map(\n (opt) => `<div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"${opt.value}\" id=\"${fieldName}-${opt.value}\" />\n <Label htmlFor=\"${fieldName}-${opt.value}\">${opt.label}</Label>\n </div>`\n )\n .join('\\n ')}\n </RadioGroup>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'multiselect':\n // TODO: Implement proper multiselect component\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <div>Multi-select field (to be implemented)</div>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'timezone':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <TimezoneSelect \n value={field.value || ''} \n onValueChange={field.onChange}\n placeholder=\"${placeholder || 'Select a timezone'}\"\n />\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'list':\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n // Generate nested fields configuration for DynamicObjectListField\n const nestedFieldsConfig = field.fields\n .map((f) => {\n const config: string[] = [\n `name: '${f.name}'`,\n `type: '${f.type}'`,\n `label: '${f.label}'`\n ]\n if (f.required) config.push('required: true')\n if (f.placeholder) config.push(`placeholder: '${f.placeholder}'`)\n if (f.options && f.options.length > 0) {\n const opts = f.options\n .map((opt) => `{ label: '${opt.label}', value: '${opt.value}' }`)\n .join(', ')\n config.push(`options: [${opts}]`)\n }\n return `{ ${config.join(', ')} }`\n })\n .join(',\\n ')\n\n return ` <DynamicObjectListField\n name=\"${fieldName}\"\n label=\"${label}\"\n fields={[\n ${nestedFieldsConfig}\n ]}${field.columns ? `\\n columns={${field.columns}}` : ''}\n />`\n }\n\n return ` <DynamicListField\n name=\"${fieldName}\"\n label=\"${label}\"\n placeholder=\"${placeholder || 'Enter value'}\"\n />`\n\n case 'file':\n case 'upload':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <FileUploadField\n value={field.value || ''}\n onChange={field.onChange}\n onBlur={field.onBlur}\n accept=\"${field.accept || '*/*'}\"\n maxSizeInMB={${field.maxFileSize || 100}}\n />\n </FormControl>\n\n\n </FormItem>\n )}\n />`\n\n case 'dynamicFields':\n // Render dynamic fields from course.applicationFields inline\n // Uses dynamicFieldErrors state for error handling since these fields aren't in the Zod schema\n return ` {/* Dynamic fields from CMS */}\n {selectedCourse?.applicationFields?.map((dynamicField, index) => {\n const fieldName = dynamicField.name || \\`dynamicField_\\${index}\\`\n const errorMessage = dynamicFieldErrors[fieldName]\n const hasError = !!errorMessage\n\n // Check showWhen condition - hide field if condition not met\n if (!isFieldVisible(dynamicField)) {\n return null\n }\n\n // Render based on field type\n switch (dynamicField.type) {\n case 'textarea':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Textarea\n id={fieldName}\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues)}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'select':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Controller\n name={fieldName as keyof FormValues}\n control={form.control}\n render={({ field: selectField }) => (\n <Select\n value={(selectField.value as string) || ''}\n onValueChange={selectField.onChange}\n >\n <SelectTrigger id={fieldName} aria-invalid={hasError} className={hasError ? 'border-destructive' : ''}>\n <SelectValue placeholder={dynamicField.placeholder || 'Select an option'} />\n </SelectTrigger>\n <SelectContent>\n {dynamicField.options?.map((option) => (\n <SelectItem key={option.value} value={option.value || ''}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'radio':\n return (\n <div key={fieldName} className=\"space-y-3\">\n <Label className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <RadioGroup\n onValueChange={(value) => form.setValue(fieldName as keyof FormValues, value as FormValues[keyof FormValues])}\n defaultValue={form.getValues(fieldName as keyof FormValues) as string}\n >\n {dynamicField.options?.map((option) => (\n <div\n key={option.value}\n className={\\`flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5 \\${hasError ? 'border-destructive' : ''}\\`}\n data-state={form.watch(fieldName as keyof FormValues) === option.value ? 'checked' : 'unchecked'}\n style={{\n borderColor: hasError ? undefined : (form.watch(fieldName as keyof FormValues) === option.value\n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)'),\n backgroundColor: form.watch(fieldName as keyof FormValues) === option.value\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem\n value={option.value || ''}\n id={\\`\\${fieldName}-\\${option.value}\\`}\n style={{\n borderColor: form.watch(fieldName as keyof FormValues) === option.value ? courseColor : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor={\\`\\${fieldName}-\\${option.value}\\`}>{option.label}</Label>\n </div>\n ))}\n </RadioGroup>\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'checkbox':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={fieldName}\n {...form.register(fieldName as keyof FormValues)}\n aria-invalid={hasError}\n className={\\`h-4 w-4 rounded border-gray-300 \\${hasError ? 'border-destructive' : ''}\\`}\n />\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n </div>\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'number':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Input\n id={fieldName}\n type=\"number\"\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues, { valueAsNumber: true })}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n default:\n // Default to text input\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Input\n id={fieldName}\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues)}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n }\n })}`\n\n default:\n return ` <div>Unknown field type: ${field.type}</div>`\n }\n }\n\n // Generate the field content\n const fieldContent = generateFieldContent()\n\n // Wrap with conditional rendering if condition is specified\n if (field.condition) {\n const watchFields = getWatchFields(field.condition)\n\n // Split condition by string literals to avoid replacing inside them\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = field.condition\n let match: RegExpExecArray | null\n\n // Extract string literals\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n // Replace field names with watched variable names for proper reactivity\n // Using useWatch hook at the top of the component ensures React re-renders\n // when the watched value changes, unlike inline form.watch() which may not trigger re-renders\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (m) => {\n // Don't replace JavaScript keywords\n if (['true', 'false', 'null', 'undefined'].includes(m)) {\n return m\n }\n // Replace field names with watched variable names (e.g., fieldName -> fieldNameValue)\n if (watchFields.includes(m)) {\n return `${m}Value`\n }\n return m\n })\n })\n\n // Reconstruct the condition\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` {${conditionCheck} && (\n${fieldContent}\n )}`\n }\n\n return fieldContent\n}\n\n// Will continue with form component generation...\n\n/**\n * Generate public form component (supports both single-step and multi-step)\n */\nexport async function generateFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n if (schema.steps && schema.steps.length > 0) {\n return generateMultiStepFormComponent(schema, options)\n }\n return generateSingleStepFormComponent(schema, options)\n}\n\n/**\n * Generate single-step form component\n */\nasync function generateSingleStepFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n\n // Get flattened fields for schema/validation (no groups)\n const fields = getAllFields(schema)\n\n // Get actual form fields (used for rendering, includes groups)\n const formFields = schema.fields || []\n\n // Determine required imports based on field types\n const hasSelect = fields.some((f) => f.type === 'select')\n const hasCheckbox = fields.some((f) => f.type === 'checkbox')\n const hasRadio = fields.some((f) => f.type === 'radio')\n const hasTextarea = fields.some((f) => f.type === 'textarea')\n const hasTimezone = fields.some((f) => f.type === 'timezone')\n const hasList = fields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n const hasObjectList = fields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)\n const hasUpload = fields.some((f) => f.type === 'upload' || f.type === 'file')\n const hasHints = fields.some((f) => f.hint)\n const hasRelationshipFields = fields.some(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n // Fields that capture URL query parameters\n const urlParamFields = fields.filter((f) => f.urlParam)\n const hasUrlParamFields = urlParamFields.length > 0\n\n // Get relationship field details\n const relationshipField = fields.find(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n const relationshipHook = relationshipField?.relationship === 'courses' ? 'useCourseBySlug' : null\n\n // Check if there's a hidden course field that should get its value from selectedCourse\n const hasHiddenCourseField =\n relationshipField?.relationship === 'courses' &&\n fields.some((f) => f.name === 'course' && f.hidden)\n\n // Check if schema has conditional fields\n const hasConditionalFields = fields.some((f) => f.condition)\n\n // Collect conditional fields for refinement\n const conditionalFields = fields.filter((f) => f.condition && f.required)\n\n // Collect all unique fields that need to be watched for showWhen conditions\n const collectWatchedFields = (formFieldList: FormField[]): string[] => {\n const watchedFields = new Set<string>()\n const collectFromField = (f: FormField) => {\n if (f.showWhen?.field) {\n watchedFields.add(f.showWhen.field)\n }\n if (f.type === 'group' && f.fields) {\n f.fields.forEach(collectFromField)\n }\n }\n formFieldList.forEach(collectFromField)\n return Array.from(watchedFields)\n }\n const watchedFieldNames = collectWatchedFields(formFields)\n const hasWatchedFields = watchedFieldNames.length > 0\n\n // Check if schema has dynamic fields\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Generate Zod schema (flattened, no groups)\n // Make conditional required fields optional in base schema\n // Also make hidden course field optional (value injected at submit time)\n const zodFields = fields\n .filter((f) => f.name)\n .map((f) => {\n // If field has a condition and is required, treat as optional in base schema\n // The requirement will be validated in superRefine when condition is met\n // Also treat hidden course field as optional since value is injected at submit time\n const treatAsOptional =\n !!(f.condition && f.required) || (hasHiddenCourseField && f.name === 'course' && f.hidden)\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n\n // Generate form fields JSX (includes groups)\n // Only use course colors for the 'application' form\n const useCourseColors = formName === 'application'\n const formFieldsJSX = formFields\n .map((f) => generateFormFieldJSX(f, { useCourseColors }))\n .join('\\n\\n')\n\n // Generate default values (flattened, no groups)\n const defaultValues = fields\n .filter((f) => f.name) // Filter out group fields\n .map((f) => {\n let defaultVal: string\n if (f.defaultValue !== undefined) {\n defaultVal = JSON.stringify(f.defaultValue)\n } else if (f.type === 'checkbox') {\n defaultVal = 'false'\n } else if (f.type === 'number') {\n defaultVal = '0'\n } else if (f.type === 'multiselect' || f.type === 'list') {\n defaultVal = '[]'\n } else if (f.type === 'select') {\n // Select fields default to undefined so placeholder shows\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && !f.required) {\n // Optional radio fields default to undefined\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && f.required && f.options && f.options.length > 0) {\n // Required radio fields default to first option value (radios don't have placeholder)\n defaultVal = `'${f.options[0].value}'`\n } else {\n defaultVal = \"''\"\n }\n return ` ${f.name}: ${defaultVal}`\n })\n .join(',\\n')\n\n const formContent = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport {\n Button,${hasCheckbox ? '\\n Checkbox,' : ''}${\n hasList ? '\\n DynamicListField,' : ''\n }${hasObjectList ? '\\n DynamicObjectListField,' : ''}${hasUpload ? '\\n FileUploadField,' : ''}\n Form,\n FormControl,${hasHints ? '\\n FormDescription,' : ''}\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,${hasRadio || includeDynamicFields ? '\\n Label,\\n RadioGroup,\\n RadioGroupItem,' : ''}${\n hasSelect || includeDynamicFields\n ? '\\n Select,\\n SelectContent,\\n SelectItem,\\n SelectTrigger,\\n SelectValue,'\n : ''\n }${hasTextarea ? '\\n Textarea,' : ''}${hasTimezone ? '\\n TimezoneSelect' : ''}\n} from '${ir.webUi}'\n${relationshipHook ? `import { ${relationshipHook} } from '${ir.hooks}'` : ''}\nimport type { Create${pascalName}SubmissionInput } from '${ir.actions(`${formName}-form`)}'\nimport { create${pascalName}Submission } from '${ir.actions(`${formName}-form`)}'${\n hasHints ? `\\nimport { renderMarkdownInline } from '${ir.lib}'` : ''\n }${hasRelationshipFields && relationshipHook ? `\\nimport { hexToOklab } from '${ir.utils}'` : ''}\nimport { useMutation } from '@tanstack/react-query'${\n hasRelationshipFields || hasUrlParamFields ? `\\nimport { useQueryState } from 'nuqs'` : ''\n }${hasRelationshipFields || hasUrlParamFields ? `\\nimport React from 'react'` : ''}\nimport { ${includeDynamicFields ? 'Controller, ' : ''}useForm${hasWatchedFields ? ', useWatch' : ''} } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\n\nconst formSchema = z.object({\n${zodFields}\n})${\n hasConditionalFields\n ? `.superRefine((data, ctx) => {\n${conditionalFields\n .map((f) => {\n const condition = f.condition || ''\n const zodType = getZodTypeForFormField(f)\n const errorMessage = zodType.match(/message: '([^']+)'/)?.[1] || `${f.label} is required`\n\n // Transform condition to use data instead of formValues\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = condition\n let match: RegExpExecArray | null\n\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (match) => {\n if (['true', 'false', 'null', 'undefined'].includes(match)) {\n return match\n }\n if (fields.find((field) => field.name === match)) {\n return `data.${match}`\n }\n return match\n })\n })\n\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` // Validate ${f.name} when condition is met\n if (${conditionCheck}) {\n if (!data.${f.name}) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: '${errorMessage}',\n path: ['${f.name}']\n })\n }\n }`\n })\n .join('\\n')}\n})`\n : ''\n }\n\ntype FormValues = z.infer<typeof formSchema>\n\nexport function ${pascalName}Form() {${\n hasUrlParamFields\n ? `\n // Query state for URL parameters\n${urlParamFields.map((f) => ` const [${f.urlParam}Param] = useQueryState('${f.urlParam}')`).join('\\n')}`\n : ''\n }${\n hasRelationshipFields\n ? `\n // Query state for relationship fields\n const [courseSlug] = useQueryState('course')\n ${relationshipHook ? `const { data: selectedCourse } = ${relationshipHook}(courseSlug)` : ''}`\n : ''\n }${\n hasRelationshipFields && relationshipHook\n ? `\n\n // Generate course color variants for radio groups\n const courseColor = selectedCourse?.color ?? '#000000'\n const radioBorderColorLight = hexToOklab(courseColor, 0.3)\n const radioBorderColorDark = hexToOklab(courseColor, 0.4)\n const radioBgColorLight = hexToOklab(courseColor, 0.1)\n const radioBgColorDark = hexToOklab(courseColor, 0.1)`\n : ''\n }\n\n const createMutation = useMutation({\n mutationFn: (data: Create${pascalName}SubmissionInput) => create${pascalName}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${(\n schema.successMessage || `${schema.label} submitted successfully`\n ).replace(/'/g, \"\\\\'\")}')\n form.reset()\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 const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaultValues}\n }\n })${\n hasWatchedFields\n ? `\n\n // Watch fields for conditional rendering\n${watchedFieldNames.map((fieldName) => ` const ${fieldName}Value = useWatch({ control: form.control, name: '${fieldName}' })`).join('\\n')}`\n : ''\n }${\n hasRelationshipFields && relationshipField\n ? `\n\n // Generate tier options from selected course\n const ${relationshipField.relationshipField}Options = React.useMemo(() => {\n if (!selectedCourse?.${relationshipField.relationshipField}) return []\n return selectedCourse.${relationshipField.relationshipField}.map((tier) => ({\n value: tier.name || '',\n label: \\`\\${tier.name} - \\${tier.upfrontFee} upfront / \\${tier.monthlyFee} monthly\\`\n }))\n }, [selectedCourse])\n\n // Auto-select first tier option when tiers load or course changes\n React.useEffect(() => {\n if (${relationshipField.relationshipField}Options.length > 0) {\n const currentValue = form.getValues('${relationshipField.name}')\n const isValidOption = ${relationshipField.relationshipField}Options.some(opt => opt.value === currentValue)\n if (!currentValue || !isValidOption) {\n form.setValue('${relationshipField.name}', ${relationshipField.relationshipField}Options[0].value)\n }\n }\n }, [${relationshipField.relationshipField}Options, form])`\n : ''\n }${\n hasUrlParamFields\n ? `\n\n // Sync hidden fields with URL query parameters\n React.useEffect(() => {\n${urlParamFields\n .map(\n (f) => ` if (${f.urlParam}Param) {\n form.setValue('${f.name}', ${f.urlParam}Param)\n }`\n )\n .join('\\n')}\n }, [${urlParamFields.map((f) => `${f.urlParam}Param`).join(', ')}, form])`\n : ''\n }\n\n${\n includeDynamicFields\n ? `\n // Track dynamic field errors separately (form.setError doesn't trigger re-renders for dynamic fields)\n const [dynamicFieldErrors, setDynamicFieldErrors] = React.useState<Record<string, string>>({})\n\n // Watch all dynamic fields that are used in showWhen conditions to trigger re-renders\n const watchedDynamicFields = React.useMemo(() => {\n const fields = new Set<string>()\n selectedCourse?.applicationFields?.forEach((f) => {\n if (f.showWhen?.field) {\n fields.add(f.showWhen.field)\n }\n })\n return Array.from(fields)\n }, [selectedCourse?.applicationFields])\n\n // Subscribe to watched fields to trigger re-renders when they change\n // The return value is used to trigger re-renders, not for data access\n form.watch(watchedDynamicFields as (keyof FormValues)[])\n\n // Check if a dynamic field should be visible based on showWhen condition\n function isFieldVisible(dynamicField: { showWhen?: { field?: string; value?: string } }): boolean {\n if (!dynamicField.showWhen?.field || !dynamicField.showWhen?.value) {\n return true // No condition, always visible\n }\n const watchFieldValue = form.getValues(dynamicField.showWhen.field as keyof FormValues)\n const conditionValue = dynamicField.showWhen.value\n // Handle comma-separated values as array\n const conditionValues = conditionValue.includes(',')\n ? conditionValue.split(',').map((v: string) => v.trim())\n : [conditionValue]\n return conditionValues.some((v: string) => String(watchFieldValue) === String(v))\n }\n\n // Validate required dynamic fields (not in Zod schema)\n // Returns true if there are validation errors\n function validateDynamicFields(): boolean {\n const errors: Record<string, string> = {}\n if (selectedCourse?.applicationFields) {\n for (const dynamicField of selectedCourse.applicationFields) {\n const fieldName = dynamicField.name\n // Skip validation if field is hidden by showWhen\n if (!isFieldVisible(dynamicField)) {\n continue\n }\n if (fieldName && dynamicField.required) {\n const fieldValue = form.getValues(fieldName as keyof FormValues)\n if (fieldValue === undefined || fieldValue === '' || fieldValue === null) {\n errors[fieldName] = \\`\\${dynamicField.label} is required\\`\n }\n }\n }\n }\n setDynamicFieldErrors(errors)\n return Object.keys(errors).length > 0\n }\n\n // Wrapper to validate dynamic fields before form submission\n function handleFormSubmit(e: React.FormEvent) {\n e.preventDefault()\n // Always validate dynamic fields first (sets errors immediately)\n validateDynamicFields()\n // Then let react-hook-form handle the rest\n form.handleSubmit(onSubmit)(e)\n }\n`\n : ''\n}\n function onSubmit(values: FormValues) {${\n includeDynamicFields\n ? `\n // Re-validate dynamic fields in case they were bypassed\n if (validateDynamicFields()) {\n return\n }\n\n // Collect dynamic field values from the form\n // Dynamic fields are stored in customFields JSON column\n const customFields: Record<string, unknown> = {}\n if (selectedCourse?.applicationFields) {\n for (const dynamicField of selectedCourse.applicationFields) {\n const fieldName = dynamicField.name\n if (fieldName) {\n const fieldValue = form.getValues(fieldName as keyof FormValues)\n if (fieldValue !== undefined && fieldValue !== '') {\n customFields[fieldName] = fieldValue\n }\n }\n }\n }`\n : ''\n }\n createMutation.mutate(${\n includeDynamicFields\n ? hasHiddenCourseField\n ? `{ ...values, course: selectedCourse?.title || '', customFields } as Create${pascalName}SubmissionInput`\n : `{ ...values, customFields } as Create${pascalName}SubmissionInput`\n : hasHiddenCourseField\n ? `{ ...values, course: selectedCourse?.title || '' } as Create${pascalName}SubmissionInput`\n : `values as Create${pascalName}SubmissionInput`\n })\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-submission-form\" onSubmit={${includeDynamicFields ? 'handleFormSubmit' : 'form.handleSubmit(onSubmit)'}} className=\"space-y-8 w-full\">\n${formFieldsJSX}\n\n <div className=\"flex items-center gap-3 pt-5\">\n <Button\n type=\"submit\"\n variant=\"default\"\n disabled={createMutation.isPending}\n size=\"lg\"\n >\n {createMutation.isPending ? \"Submitting...\" : \"${\n schema.submitButtonText || 'Send Message'\n }\"}\n </Button>\n </div>\n </form>\n </Form>\n )\n}\n`\n\n const componentPath = path.join(paths.app, 'components/forms', `${formName}-form.tsx`)\n ensureDir(path.dirname(componentPath))\n\n if (fs.existsSync(componentPath) && !options.force) {\n console.warn(`⚠️ Form component already exists: ${componentPath}. Use --force to overwrite.`)\n return componentPath\n }\n\n fs.writeFileSync(componentPath, formContent, 'utf-8')\n console.log(` ✓ Form component generated: ${componentPath}`)\n\n return componentPath\n}\n\n/**\n * Generate multi-step form component\n */\nasync function generateMultiStepFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const steps = schema.steps || []\n const allFields = getAllFields(schema)\n\n // Determine required imports based on field types\n const hasSelect = allFields.some((f) => f.type === 'select')\n const hasCheckbox = allFields.some((f) => f.type === 'checkbox')\n const hasRadio = allFields.some((f) => f.type === 'radio')\n const hasTextarea = allFields.some((f) => f.type === 'textarea')\n const hasTimezone = allFields.some((f) => f.type === 'timezone')\n const hasList = allFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n const hasObjectList = allFields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)\n const hasUpload = allFields.some((f) => f.type === 'upload' || f.type === 'file')\n const hasHints = allFields.some((f) => f.hint)\n const hasHiddenFields = allFields.some((f) => f.hidden)\n const includeDynamicFields = hasDynamicFields(schema)\n const hasRelationshipFields = allFields.some(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n\n // Get relationship field details\n const relationshipField = allFields.find(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n const relationshipHook = relationshipField?.relationship === 'courses' ? 'useCourseBySlug' : null\n\n // Check if there's a hidden course field that should get its value from selectedCourse\n const hasHiddenCourseField =\n relationshipField?.relationship === 'courses' &&\n allFields.some((f) => f.name === 'course' && f.hidden)\n\n // Generate Zod schema for all fields (filter out groups - they don't have names)\n // Make hidden course field optional (value injected at submit time)\n const zodFields = allFields\n .filter((f) => f.name)\n .map((f) => {\n const treatAsOptional = hasHiddenCourseField && f.name === 'course' && f.hidden\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n\n // Generate per-step Zod schemas (filter out groups)\n const stepSchemas = steps\n .map((step, idx) => {\n const stepFields = step.fields\n .filter((f) => f.name)\n .map((f) => {\n const treatAsOptional = hasHiddenCourseField && f.name === 'course' && f.hidden\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n return `const step${idx + 1}Schema = z.object({\n${stepFields}\n})`\n })\n .join('\\n\\n')\n\n // Generate default values (filter out groups - they don't have names)\n const defaultValues = allFields\n .filter((f) => f.name) // Filter out group fields which don't have names\n .map((f) => {\n let defaultVal: string\n if (f.defaultValue !== undefined) {\n defaultVal = JSON.stringify(f.defaultValue)\n } else if (f.type === 'checkbox') {\n defaultVal = 'false'\n } else if (f.type === 'number') {\n defaultVal = '0'\n } else if (f.type === 'multiselect' || f.type === 'list') {\n defaultVal = '[]'\n } else if (f.type === 'select') {\n // Select fields default to undefined so placeholder shows\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && !f.required) {\n // Optional radio fields default to undefined\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && f.required && f.options && f.options.length > 0) {\n // Required radio fields default to first option value (radios don't have placeholder)\n defaultVal = `\"${f.options[0].value}\"`\n } else {\n defaultVal = '\"\"'\n }\n return ` ${f.name}: ${defaultVal}`\n })\n .join(',\\n')\n\n // Generate step components\n // Only use course colors for the 'application' form\n const useCourseColors = formName === 'application'\n const stepComponents = steps\n .map((step, idx) => {\n const stepFieldsJSX = step.fields\n .map((f) => generateFormFieldJSX(f, { useCourseColors }))\n .join('\\n\\n')\n return ` {currentStep === ${idx} && (\n <>\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold\">{STEPS[${idx}].label}</h3>\n ${\n step.description\n ? `<p className=\"text-sm text-muted-foreground\">${step.description}</p>`\n : ''\n }\n </div>\n <div className=\"space-y-4\">\n${stepFieldsJSX}\n </div>\n </>\n )}`\n })\n .join('\\n\\n')\n\n const formContent = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport {\n Button,\n Card,\n CardContent,\n ${hasCheckbox ? 'Checkbox,' : ''}\n ${hasList ? 'DynamicListField,' : ''}\n ${hasObjectList ? 'DynamicObjectListField,' : ''}\n ${hasUpload ? 'FileUploadField,' : ''}\n Form,\n FormControl,\n ${hasHints ? 'FormDescription,' : ''}\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n ${hasRadio || includeDynamicFields ? 'Label,' : ''}\n ${hasRadio || includeDynamicFields ? 'RadioGroup, RadioGroupItem,' : ''}\n ${hasSelect || includeDynamicFields ? 'Select, SelectContent, SelectItem, SelectTrigger, SelectValue,' : ''}\n ${hasTextarea ? 'Textarea,' : ''}\n Tabs,\n TabsList,\n TabsTrigger,\n ${hasTimezone ? 'TimezoneSelect' : ''}\n} from '${ir.webUi}'\nimport { useCreate${pascalName}Submission, useLocalStorage${\n relationshipHook ? `, ${relationshipHook}` : ''\n } } from '${ir.hooks}'${hasHints ? `\\nimport { renderMarkdownInline } from '${ir.lib}'` : ''}\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport React from 'react'\nimport { useForm } from 'react-hook-form'\nimport { z } from 'zod'\n\n// Full form schema\nconst formSchema = z.object({\n${zodFields}\n})\n\n// Per-step schemas for validation\n${stepSchemas}\n\ntype FormValues = z.infer<typeof formSchema>\n\nconst STEPS = ${JSON.stringify(steps.map((s) => ({ name: s.name, label: s.label })))}\nconst TOTAL_STEPS = ${steps.length}\n\nexport function ${pascalName}Form() {\n const createMutation = useCreate${pascalName}Submission()\n const [isPending, startTransition] = React.useTransition()\n const [currentStep, setCurrentStep] = useQueryState('step', parseAsInteger.withDefault(0))\n ${\n hasRelationshipFields || hasHiddenFields\n ? `\n // Query state for relationship fields\n const [courseSlug] = useQueryState('course')\n ${relationshipHook ? `const { data: selectedCourse } = ${relationshipHook}(courseSlug)` : ''}`\n : ''\n }\n \n // LocalStorage persistence\n const storage = useLocalStorage<Partial<FormValues>>('form-${formName}-draft')\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: storage.getItem() || {\n${defaultValues}\n }\n })\n\n // Auto-save to localStorage on field changes\n const formValues = form.watch()\n React.useEffect(() => {\n storage.setItem(formValues)\n }, [formValues, storage])\n ${\n hasRelationshipFields && relationshipField\n ? `\n // Generate tier options from selected course\n const ${relationshipField.relationshipField}Options = React.useMemo(() => {\n if (!selectedCourse?.${relationshipField.relationshipField}) return []\n return selectedCourse.${relationshipField.relationshipField}.map((tier) => ({\n value: tier.name || '',\n label: \\`\\${tier.name} - \\${tier.upfrontFee} upfront / \\${tier.monthlyFee} monthly\\`\n }))\n }, [selectedCourse])\n\n // Auto-select first tier option when tiers load or course changes\n React.useEffect(() => {\n if (${relationshipField.relationshipField}Options.length > 0) {\n const currentValue = form.getValues('${relationshipField.name}')\n const isValidOption = ${relationshipField.relationshipField}Options.some(opt => opt.value === currentValue)\n if (!currentValue || !isValidOption) {\n form.setValue('${relationshipField.name}', ${relationshipField.relationshipField}Options[0].value)\n }\n }\n }, [${relationshipField.relationshipField}Options, form])`\n : ''\n }\n\n const validateStep = React.useCallback(async (step: number) => {\n const stepFieldNames = STEPS[step] ? ${JSON.stringify(\n steps.map((s) => {\n const flattenFieldNames = (flds: FormField[]): string[] => {\n return flds.flatMap((f) => {\n if (f.type === 'group' && f.fields) {\n return flattenFieldNames(f.fields)\n }\n return f.name ? [f.name] : []\n })\n }\n return flattenFieldNames(s.fields)\n })\n )}[step] : []\n const isValid = await form.trigger(stepFieldNames.length > 0 ? stepFieldNames : undefined)\n return isValid\n }, [form])\n\n const handleNext = React.useCallback(async () => {\n const isValid = await validateStep(currentStep)\n if (isValid && currentStep < TOTAL_STEPS - 1) {\n setCurrentStep(currentStep + 1)\n }\n }, [currentStep, validateStep, setCurrentStep])\n\n const handlePrevious = React.useCallback(() => {\n if (currentStep > 0) {\n setCurrentStep(currentStep - 1)\n }\n }, [currentStep, setCurrentStep])\n\n const onSubmit = async (data: FormValues) => {\n // Final validation\n const isValid = await form.trigger()\n if (!isValid) return\n\n startTransition(() => {\n createMutation.mutate(${\n hasHiddenCourseField ? `{ ...data, course: selectedCourse?.title || '' }` : 'data'\n }, {\n onSuccess: () => {\n // Clear localStorage on successful submission\n storage.removeItem()\n form.reset()\n }\n })\n })\n }\n\n return (\n <div className=\"mx-auto max-w-2xl\">\n {/* Stepper/Tabs */}\n <Tabs value={currentStep.toString()} className=\"mb-8\">\n <TabsList className=\"grid w-full grid-cols-${steps.length}\">\n {STEPS.map((step, index) => (\n <TabsTrigger\n key={step.name}\n value={index.toString()}\n onClick={() => setCurrentStep(index)}\n disabled={index > currentStep}\n >\n {step.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n\n {/* Progress Indicator */}\n <div className=\"mb-6\">\n <p className=\"text-sm text-muted-foreground\">\n Step {currentStep + 1} of {TOTAL_STEPS}\n </p>\n </div>\n\n <Card>\n <CardContent className=\"pt-6\">\n <Form {...form}>\n <form id=\"${schema.name}-submission-multistep-form\" onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n {/* Step Content */}\n${stepComponents}\n\n {/* Navigation Buttons */}\n <div className=\"flex justify-between pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handlePrevious}\n disabled={currentStep === 0}\n >\n Previous\n </Button>\n\n {currentStep < TOTAL_STEPS - 1 ? (\n <Button type=\"button\" onClick={handleNext}>\n Next\n </Button>\n ) : (\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Submitting...' : '${schema.submitButtonText || 'Submit'}'}\n </Button>\n )}\n </div>\n </form>\n </Form>\n </CardContent>\n </Card>\n </div>\n )\n}\n`\n\n const componentPath = path.join(paths.app, 'components/forms', `${formName}-form.tsx`)\n ensureDir(path.dirname(componentPath))\n\n if (fs.existsSync(componentPath) && !options.force) {\n console.warn(`⚠️ Form component already exists: ${componentPath}. Use --force to overwrite.`)\n return componentPath\n }\n\n fs.writeFileSync(componentPath, formContent, 'utf-8')\n console.log(` ✓ Multi-step form component generated: ${componentPath}`)\n\n return componentPath\n}\n\n/**\n * Main form generation orchestrator\n */\nexport async function generateForm(\n formName: string,\n options: GeneratorOptions = {}\n): Promise<void> {\n const paths = getPaths()\n const schemaPath = path.join(paths.schemas, 'forms', `${formName}.json`)\n\n if (!fs.existsSync(schemaPath)) {\n throw new Error(`Form schema not found: ${schemaPath}`)\n }\n\n const schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n const schema: FormSchema = JSON.parse(schemaContent)\n\n console.log(`\\n📝 Generating form: ${schema.label}\\n`)\n\n try {\n // 1. Generate database schema\n console.log('1️⃣ Generating database schema...')\n await generateFormDatabase(schema, options)\n\n // 2. Generate server actions\n console.log('2️⃣ Generating server actions...')\n await generateFormActions(schema, options)\n\n // 3. Generate React Query hook\n console.log('3️⃣ Generating React Query hook...')\n await generateFormHook(schema, options)\n\n // 4. Generate form component\n console.log('4️⃣ Generating form component...')\n await generateFormComponent(schema, options)\n\n // 5. Generate email template if notificationEmail is set\n if (schema.notificationEmail) {\n console.log('5️⃣ Generating email template...')\n await generateEmailTemplate(schema, options)\n }\n\n // 6. Generate admin UI (columns, table, page)\n console.log('6️⃣ Generating admin UI...')\n // Admin UI generation will be simplified for MVP\n\n // 7. Update navigation\n console.log('7️⃣ Updating navigation...')\n await updateFormNavigation(schema, options)\n\n // 7. Generate admin UI pages\n console.log('\\n🎨 Generating admin UI pages...')\n await generateFormAdminPages(schema, options)\n\n console.log('\\n✅ Form generation complete!\\n')\n console.log('📁 Generated files:')\n console.log(` - Database schema updated`)\n console.log(` - Actions: packages/lib/src/actions/${formName}-form.ts`)\n console.log(` - Hook: packages/hooks/src/use-${formName}-form.ts`)\n console.log(` - Component: apps/web/components/forms/${formName}-form.tsx`)\n if (schema.notificationEmail) {\n console.log(` - Email template: apps/web/emails/${formName}-submission.tsx`)\n }\n console.log(` - Navigation updated (Forms group)`)\n\n // Run database migrations if not skipped\n if (!options.skipMigration) {\n console.log('\\n🗄️ Running database migrations...')\n\n // Check if DATABASE_URL is configured\n if (!process.env.DATABASE_URL) {\n console.warn('\\n⚠️ DATABASE_URL environment variable not found')\n console.warn(' Skipping database migration')\n console.warn(' To run migrations later:')\n console.warn(' 1. Configure DATABASE_URL in your .env file')\n console.warn(' 2. Run: pnpm db:push')\n } else {\n try {\n const { execSync } = await import('node:child_process')\n execSync('pnpm db:push', {\n cwd: paths.root,\n stdio: 'inherit'\n })\n console.log('\\n ✓ Database schema synced')\n } catch (error) {\n console.error('\\n⚠️ Database migration failed')\n const errorMessage = error instanceof Error ? error.message : String(error)\n console.error(' You can run manually: pnpm db:push')\n console.error(` Error: ${errorMessage}`)\n }\n }\n }\n\n // Run linter and formatter as final step\n console.log('\\n🎨 Running formatter and linter...')\n try {\n const { execSync } = await import('node:child_process')\n execSync('pnpm lint:fix', {\n cwd: paths.root,\n stdio: 'pipe'\n })\n console.log(' ✓ Code formatted and linted with Biome')\n } catch (_error) {\n console.warn(' ⚠️ Linter encountered issues (this is usually fine)')\n console.warn(' You can run: pnpm lint:fix manually if needed')\n }\n\n console.log('\\n📝 Next steps:')\n console.log(` 1. Review the generated files`)\n console.log(\n ` 2. Set up environment variables (RESEND_API_KEY, NOTIFICATION_EMAIL, FROM_EMAIL)`\n )\n console.log(` 3. Import and use the form component in your app:`)\n console.log(\n ` import { ${toPascalCase(formName)}Form } from '@/components/forms/${formName}-form'`\n )\n console.log('')\n } catch (error) {\n console.error('\\n❌ Form generation failed:', error)\n throw error\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, GeneratorOptions } from '../types'\nimport { getPaths, toKebabCase } from '../utils'\n\ninterface NavigationSubItem {\n title: string\n url: string\n icon?: string\n}\n\ninterface NavigationItem {\n title: string\n url: string\n icon: string\n items?: NavigationSubItem[]\n}\n\n/**\n * Parse the existing navigation.ts file and extract navigation items\n */\nfunction parseNavigationFile(content: string): NavigationItem[] {\n // Extract the array content between [ and ] after 'export const adminNavigation ='\n const match = content.match(/export const adminNavigation\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*as const/)\n if (!match) {\n return []\n }\n\n const arrayContent = match[1]\n\n // Parse each navigation item object\n const items: NavigationItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < arrayContent.length; i++) {\n const char = arrayContent[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n // Parse the current item\n const item = parseNavigationItem(currentItem)\n if (item) {\n items.push(item)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return items\n}\n\n/**\n * Parse a single navigation item object string\n */\nfunction parseNavigationItem(itemStr: string): NavigationItem | null {\n const titleMatch = itemStr.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = itemStr.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = itemStr.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!titleMatch || !urlMatch || !iconMatch) {\n return null\n }\n\n const item: NavigationItem = {\n title: titleMatch[1],\n url: urlMatch[1],\n icon: iconMatch[1]\n }\n\n // Check for nested items array\n const itemsMatch = itemStr.match(/items:\\s*\\[([\\s\\S]*?)\\]/)\n if (itemsMatch) {\n item.items = parseSubItems(itemsMatch[1])\n }\n\n return item\n}\n\n/**\n * Parse sub-items from an items array string\n */\nfunction parseSubItems(itemsStr: string): NavigationSubItem[] {\n const subItems: NavigationSubItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < itemsStr.length; i++) {\n const char = itemsStr[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n const titleMatch = currentItem.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = currentItem.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = currentItem.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (titleMatch && urlMatch) {\n const subItem: NavigationSubItem = {\n title: titleMatch[1],\n url: urlMatch[1]\n }\n if (iconMatch) {\n subItem.icon = iconMatch[1]\n }\n subItems.push(subItem)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return subItems\n}\n\n/**\n * Generate TypeScript code for navigation items\n */\nfunction generateNavigationCode(items: NavigationItem[]): string {\n const lines: string[] = [\n \"import type { AdminNavigationItem } from '../types'\",\n '',\n 'export const adminNavigation = ['\n ]\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n\n if (item.items && item.items.length > 0) {\n // Item with sub-items\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}',`)\n lines.push(' items: [')\n\n for (let j = 0; j < item.items.length; j++) {\n const subItem = item.items[j]\n const isLastSub = j === item.items.length - 1\n lines.push(' {')\n lines.push(` title: '${subItem.title}',`)\n lines.push(` url: '${subItem.url}'${subItem.icon ? ',' : ''}`)\n if (subItem.icon) {\n lines.push(` icon: '${subItem.icon}'`)\n }\n lines.push(` }${isLastSub ? '' : ','}`)\n }\n\n lines.push(' ]')\n lines.push(` }${isLast ? '' : ','}`)\n } else {\n // Simple item\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}'`)\n lines.push(` }${isLast ? '' : ','}`)\n }\n }\n\n lines.push('] as const satisfies readonly AdminNavigationItem[]')\n lines.push('')\n\n return lines.join('\\n')\n}\n\n/**\n * Update navigation.ts to include form submission item in Forms group\n */\nexport async function updateFormNavigation(\n schema: FormSchema,\n options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const navFilePath = path.join(paths.data, 'src/admin/navigation.ts')\n\n // Read existing navigation\n let navigation: NavigationItem[] = []\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n navigation = parseNavigationFile(content)\n }\n\n // Find or create Forms group\n let formsGroup = navigation.find((item) => item.title === 'Forms')\n\n if (!formsGroup) {\n formsGroup = {\n title: 'Forms',\n url: '#',\n icon: 'FileInput',\n items: []\n }\n navigation.push(formsGroup)\n }\n\n // Ensure items array exists\n if (!formsGroup.items) {\n formsGroup.items = []\n }\n\n // Create form submissions menu item\n const kebabName = toKebabCase(schema.name)\n const submissionUrl = `/admin/forms/${kebabName}`\n const existingIndex = formsGroup.items.findIndex((item) => item.url === submissionUrl)\n\n const newItem: NavigationSubItem = {\n title: schema.label,\n url: submissionUrl,\n icon: 'Inbox'\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n // Update existing item\n formsGroup.items[existingIndex] = newItem\n } else {\n console.warn(\n ` ⚠️ Navigation item already exists for \"${schema.name}\" submissions. Use --force to overwrite.`\n )\n return\n }\n } else {\n // Add new item and sort alphabetically\n formsGroup.items.push(newItem)\n formsGroup.items.sort((a, b) => a.title.localeCompare(b.title))\n }\n\n // Reorganize navigation: Home, Forms (if exists), other items alphabetically, Users last\n const home = navigation.find((item) => item.url === '/admin')\n const forms = navigation.find((item) => item.title === 'Forms')\n const users = navigation.find((item) => item.title === 'Users')\n const others = navigation.filter(\n (item) => item.url !== '/admin' && item.title !== 'Forms' && item.title !== 'Users'\n )\n\n others.sort((a, b) => a.title.localeCompare(b.title))\n\n navigation = [\n ...(home ? [home] : []),\n ...(forms ? [forms] : []),\n ...others,\n ...(users ? [users] : [])\n ]\n\n // Generate and write updated navigation\n const code = generateNavigationCode(navigation)\n fs.writeFileSync(navFilePath, code, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Generate React Query hooks in packages/hooks/src/\n */\nexport async function generateHook(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const hooksDir = path.join(paths.hooks, 'src')\n ensureDir(hooksDir)\n\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(hooksDir, hookFileName)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\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\n const singularHookName = `use${pascalSingular}`\n const singularHookContent = `\nexport function ${singularHookName}(id: number | null | undefined): UseQueryResult<${pascalSingular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singularName}', id],\n queryFn: () => (id ? get${pascalSingular}ById(id) : Promise.resolve(null)),\n enabled: !!id,\n staleTime: 0 // Refetch when query is invalidated\n })\n}\n`\n\n const slugHookName = `use${pascalSingular}BySlug`\n const slugHookContent = hasSlugField\n ? `\nexport function ${slugHookName}(slug: string | null | undefined): UseQueryResult<${pascalSingular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singularName}', 'slug', slug],\n queryFn: () => (slug ? get${pascalSingular}BySlug(slug) : Promise.resolve(null)),\n enabled: !!slug,\n staleTime: 0 // Refetch when query is invalidated\n })\n}\n`\n : ''\n\n // Check if file exists\n if (fs.existsSync(hookFilePath)) {\n const existingContent = fs.readFileSync(hookFilePath, 'utf-8')\n let updatedContent = existingContent\n let hasUpdates = false\n\n // If singular hook is missing, add it\n if (!existingContent.includes(`export function ${singularHookName}(`)) {\n const importRegex = new RegExp(`import\\\\s*{([^}]+)}\\\\s*from\\\\s*['\"]${ir.libEscaped}['\"]`)\n const match = updatedContent.match(importRegex)\n\n if (match) {\n const imports = match[1].trim()\n const needsFunction = !imports.includes(`get${pascalSingular}ById`)\n const needsType = !imports.includes(`${pascalSingular}Data`)\n\n if (needsFunction || needsType) {\n let newImports = imports\n if (needsFunction) {\n newImports += `, get${pascalSingular}ById`\n }\n if (needsType) {\n newImports += `, type ${pascalSingular}Data`\n }\n updatedContent = updatedContent.replace(\n importRegex,\n `import { ${newImports} } from \"${ir.lib}\"`\n )\n }\n }\n\n // Ensure UseQueryResult is imported from react-query\n if (!updatedContent.includes('UseQueryResult')) {\n const reactQueryImportRegex = /import\\s*{([^}]+)}\\s*from\\s*['\"]@tanstack\\/react-query['\"]/\n const rqMatch = updatedContent.match(reactQueryImportRegex)\n if (rqMatch) {\n const newImports = `type UseQueryResult, ${rqMatch[1].trim()}`\n updatedContent = updatedContent.replace(\n reactQueryImportRegex,\n `import { ${newImports} } from \"@tanstack/react-query\"`\n )\n }\n }\n\n updatedContent = updatedContent.trimEnd() + singularHookContent\n hasUpdates = true\n }\n\n // If slug hook is missing and schema has slug field, add it\n if (hasSlugField && !existingContent.includes(`export function ${slugHookName}(`)) {\n const importRegex = new RegExp(`import\\\\s*{([^}]+)}\\\\s*from\\\\s*['\"]${ir.libEscaped}['\"]`)\n const match = updatedContent.match(importRegex)\n\n if (match) {\n const imports = match[1].trim()\n const needsFunction = !imports.includes(`get${pascalSingular}BySlug`)\n\n if (needsFunction) {\n let newImports = imports\n newImports += `, get${pascalSingular}BySlug`\n updatedContent = updatedContent.replace(\n importRegex,\n `import { ${newImports} } from \"${ir.lib}\"`\n )\n }\n }\n\n updatedContent = updatedContent.trimEnd() + slugHookContent\n hasUpdates = true\n }\n\n if (hasUpdates) {\n fs.writeFileSync(hookFilePath, updatedContent, 'utf-8')\n console.log(` ✅ Updated hooks in: ${hookFileName}`)\n return `packages/hooks/src/${hookFileName}`\n }\n\n if (!options.force) {\n console.warn(` ⚠️ Hook file already exists: ${hookFileName}. Use --force to overwrite.`)\n return `packages/hooks/src/${hookFileName}`\n }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // Generate distinct values hooks for filters (each filter has its own dedicated server action)\n const distinctValuesHooks = hasFilters\n ? schema\n .filters!.map((filter) => {\n const pascalField = toPascalCase(filter.field)\n return `\nexport function use${pascalPlural}Distinct${pascalField}(): UseQueryResult<string[], Error> {\n return useQuery({\n queryKey: ['${pluralName}', 'distinct', '${filter.field}'],\n queryFn: () => getDistinct${pascalPlural}${pascalField}()\n })\n}`\n })\n .join('\\n')\n : ''\n\n // Generate full content for new file or --force overwrite\n const importFunctions = hasSlugField\n ? `get${pascalSingular}ById, get${pascalSingular}BySlug, get${pascalPlural}`\n : `get${pascalSingular}ById, get${pascalPlural}`\n\n // Import each distinct function for each filter field\n const importDistinctFunctions = hasFilters\n ? schema.filters!.map((f) => `getDistinct${pascalPlural}${toPascalCase(f.field)}`).join(', ')\n : ''\n const importDistinctFunction = hasFilters ? `, ${importDistinctFunctions}` : ''\n\n // Build filter parameters for use hook\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\n const filtersObject = hasFilters\n ? `const filters: Get${pascalPlural}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${pascalPlural}(Object.keys(filters).length > 0 ? filters : undefined)`\n : `const filters: Get${pascalPlural}Filters | undefined = search ? { search } : undefined\n return get${pascalPlural}(filters)`\n\n const content = `import {\n ${importFunctions}${importDistinctFunction},\n type ${pascalSingular}Data,\n type ${pascalPlural}Response,\n type Get${pascalPlural}Filters\n} from '${ir.actions(schema.name)}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${pascalPlural}(\n ${allParams ? `${allParams},` : ''}\n options?: { enabled?: boolean }\n): UseQueryResult<${pascalPlural}Response, Error> {\n return useQuery({\n queryKey: ['${pluralName}', ${queryKeyParts}],\n queryFn: () => {\n ${filtersObject}\n },\n enabled: options?.enabled ?? true,\n refetchOnMount: 'always'\n })\n}\n${singularHookContent}${slugHookContent}${distinctValuesHooks}`\n\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n // Update hooks/src/index.ts to export new hook\n const indexPath = path.join(hooksDir, 'index.ts')\n const exportLine = `export * from './${hookFileName.replace('.ts', '')}'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n }\n\n return `packages/hooks/src/${hookFileName}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport { getPaths } from '../utils'\n\ninterface NavigationSubItem {\n title: string\n url: string\n icon?: string\n}\n\ninterface NavigationItem {\n title: string\n url: string\n icon: string\n items?: NavigationSubItem[]\n}\n\n/**\n * Parse the existing navigation.ts file and extract navigation items\n */\nfunction parseNavigationFile(content: string): NavigationItem[] {\n // Extract the array content between [ and ] after 'export const adminNavigation ='\n const match = content.match(/export const adminNavigation\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*as const/)\n if (!match) {\n return []\n }\n\n const arrayContent = match[1]\n\n // Parse each navigation item object\n const items: NavigationItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < arrayContent.length; i++) {\n const char = arrayContent[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n // Parse the current item\n const item = parseNavigationItem(currentItem)\n if (item) {\n items.push(item)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return items\n}\n\n/**\n * Parse a single navigation item object string\n */\nfunction parseNavigationItem(itemStr: string): NavigationItem | null {\n const titleMatch = itemStr.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = itemStr.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = itemStr.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!titleMatch || !urlMatch || !iconMatch) {\n return null\n }\n\n const item: NavigationItem = {\n title: titleMatch[1],\n url: urlMatch[1],\n icon: iconMatch[1]\n }\n\n // Check for nested items array\n const itemsMatch = itemStr.match(/items:\\s*\\[([\\s\\S]*?)\\]/)\n if (itemsMatch) {\n item.items = parseSubItems(itemsMatch[1])\n }\n\n return item\n}\n\n/**\n * Parse sub-items from an items array string\n */\nfunction parseSubItems(itemsStr: string): NavigationSubItem[] {\n const subItems: NavigationSubItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < itemsStr.length; i++) {\n const char = itemsStr[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n const titleMatch = currentItem.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = currentItem.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = currentItem.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (titleMatch && urlMatch) {\n const subItem: NavigationSubItem = {\n title: titleMatch[1],\n url: urlMatch[1]\n }\n if (iconMatch) {\n subItem.icon = iconMatch[1]\n }\n subItems.push(subItem)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return subItems\n}\n\n/**\n * Generate TypeScript code for navigation items\n */\nfunction generateNavigationCode(items: NavigationItem[]): string {\n const lines: string[] = [\n \"import type { AdminNavigationItem } from '../types'\",\n '',\n 'export const adminNavigation = ['\n ]\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n\n if (item.items && item.items.length > 0) {\n // Item with sub-items\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}',`)\n lines.push(' items: [')\n\n for (let j = 0; j < item.items.length; j++) {\n const subItem = item.items[j]\n const isLastSub = j === item.items.length - 1\n lines.push(' {')\n lines.push(` title: '${subItem.title}',`)\n lines.push(` url: '${subItem.url}'${subItem.icon ? ',' : ''}`)\n if (subItem.icon) {\n lines.push(` icon: '${subItem.icon}'`)\n }\n lines.push(` }${isLastSub ? '' : ','}`)\n }\n\n lines.push(' ]')\n lines.push(` }${isLast ? '' : ','}`)\n } else {\n // Simple item\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}'`)\n lines.push(` }${isLast ? '' : ','}`)\n }\n }\n\n lines.push('] as const satisfies readonly AdminNavigationItem[]')\n lines.push('')\n\n return lines.join('\\n')\n}\n\n/**\n * Update navigation.ts to include new menu item\n */\nexport async function updateNavigation(schema: Schema, options: GeneratorOptions): Promise<void> {\n const paths = getPaths()\n const navFilePath = path.join(paths.data, 'src/admin/navigation.ts')\n\n // Read existing navigation\n let navigation: NavigationItem[] = []\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n navigation = parseNavigationFile(content)\n }\n\n // Check if item already exists\n const existingIndex = navigation.findIndex((item) => item.url === `/admin/${schema.name}`)\n\n const newItem: NavigationItem = {\n title: schema.label,\n url: `/admin/${schema.name}`,\n icon: schema.icon\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n // Update existing item\n navigation[existingIndex] = newItem\n } else {\n console.warn(\n ` ⚠️ Navigation item already exists for \"${schema.name}\". Use --force to overwrite.`\n )\n return\n }\n } else {\n // Add new item and sort alphabetically (except Home should always be first, Forms second, Users last)\n const home = navigation.find((item) => item.url === '/admin')\n const forms = navigation.find((item) => item.title === 'Forms')\n const users = navigation.find((item) => item.title === 'Users')\n const others = navigation.filter(\n (item) => item.url !== '/admin' && item.title !== 'Forms' && item.title !== 'Users'\n )\n\n others.push(newItem)\n others.sort((a, b) => a.title.localeCompare(b.title))\n\n navigation = [\n ...(home ? [home] : []),\n ...(forms ? [forms] : []),\n ...others,\n ...(users ? [users] : [])\n ]\n }\n\n // Generate and write updated navigation\n const code = generateNavigationCode(navigation)\n fs.writeFileSync(navFilePath, code, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport { ensureDir, getPaths, pluralize, toKebabCase, toPascalCase } from '../utils'\n\n/**\n * Generate page component\n */\nexport async function generatePage(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const pageFilePath = path.join(adminDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Page file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/page.tsx`\n }\n\n const pluralName = pluralize(schema.name)\n const pascalPlural = toPascalCase(pluralName)\n const tableFileName = toKebabCase(pluralName)\n\n const content = `import * as React from \"react\";\nimport { AdminSubHeader } from \"@/components/admin\";\nimport { AdminPageSkeleton } from \"@/components/admin/admin-page-skeleton\";\nimport { columns } from \"./columns\";\nimport { ${pascalPlural}PageContent } from \"./${tableFileName}-page-content\";\n\nexport default function Page() {\n return (\n <React.Suspense fallback={<AdminPageSkeleton />}>\n <div className=\"flex flex-col\">\n <AdminSubHeader />\n <${pascalPlural}PageContent columns={columns} />\n </div>\n </React.Suspense>\n );\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n singularizeLabel,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate page content component (client component with state management)\n */\nexport async function generatePageContent(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const fileName = `${toKebabCase(pluralName)}-page-content.tsx`\n const filePath = path.join(adminDir, fileName)\n\n // Check if file exists\n if (fs.existsSync(filePath) && !options.force) {\n console.warn(` ⚠️ Page content file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${fileName}`\n }\n\n const hasCreateAction = schema.actions?.create ?? false\n const hasDeleteAction = schema.actions?.delete ?? false\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // Generate lucide icons list\n const lucideIcons: string[] = ['Search']\n if (hasCreateAction) lucideIcons.push('FilePlus')\n if (hasDeleteAction) lucideIcons.push('Trash2')\n if (hasFilters) lucideIcons.push('Check', 'ChevronsUpDown')\n\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${hasCreateAction ? \"import Link from 'next/link'\\n\" : ''}import { parseAsString${hasDeleteAction ? ', parseAsArrayOf, parseAsInteger' : ''}, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\n${\n hasDeleteAction ? \"import { toast } from 'sonner'\\n\" : ''\n}import { AdminPageHeader } from '@/components/admin'\n`\n\n if (hasDeleteAction) {\n imports += `import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Input${\n hasFilters\n ? `,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n Popover,\n PopoverContent,\n PopoverTrigger`\n : ''\n }\n} from '${ir.adminUi}'\n`\n } else {\n // Always need Button for search submit\n imports += `import { Button, Input${\n hasFilters\n ? `, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger`\n : ''\n } } from '${ir.adminUi}'\\n`\n }\n\n // Add filter hooks import\n const filterHooksImport = hasFilters\n ? schema.filters!.map((f) => `use${pascalPlural}Distinct${toPascalCase(f.field)}`).join(', ')\n : ''\n\n imports += `${\n hasFilters ? `import { ${filterHooksImport} } from '${ir.hooks}'\\n` : ''\n }import type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n${\n hasDeleteAction ? `import { deleteBulk${pascalPlural} } from '${ir.actions(schema.name)}'\\n` : ''\n}${hasFilters ? `import { cn } from '${ir.utils}'\\n` : ''}import { ${pascalPlural}Table } from './${toKebabCase(pluralName)}-table'\n`\n\n const queryClientLogic = hasDeleteAction ? ` const queryClient = useQueryClient()` : ''\n\n // SearchButton component using useFormStatus\n const searchButtonComponent = `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 management\n const filterLogic = hasFilters\n ? schema\n .filters!.map((filter) => {\n return ` const [${filter.field}, set${toPascalCase(filter.field)}] = useQueryState('${filter.field}', parseAsString.withDefault(''))\n const { data: ${filter.field}Options } = use${pascalPlural}Distinct${toPascalCase(filter.field)}()\n const [${filter.field}ComboboxOpen, set${toPascalCase(filter.field)}ComboboxOpen] = React.useState(false)`\n })\n .join('\\n')\n : ''\n\n // Search state management - action-based\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`\n\n const deleteLogic = hasDeleteAction\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${pascalPlural}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} ${singularName}\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${pluralName}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n`\n : ''\n\n const deleteButton = hasDeleteAction\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 ? '${singularName}' : '${pluralName}'}\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 ? '${singularName}' : '${pluralName}'}.\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 const createButton = hasCreateAction\n ? ` <Button asChild>\n <Link href=\"/admin/${schema.name}/new\">\n <FilePlus className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Create ${singularizeLabel(schema.label)}\n </Link>\n </Button>`\n : ''\n\n // GitHub sync button removed - no longer using GitHub sync\n\n // Build table props with filters\n const filterPropsString = hasFilters\n ? schema.filters!.map((f) => `${f.field}={${f.field}}`).join(' ')\n : ''\n const allTableProps = filterPropsString\n ? `search={search} ${filterPropsString}`\n : 'search={search}'\n\n const tableProps = hasDeleteAction\n ? `columns={columns} selectedIds={selectedIds} setSelectedIds={setSelectedIds} ${allTableProps}`\n : `columns={columns} selectedIds={[]} setSelectedIds={() => {}} ${allTableProps}`\n\n // Filter dropdown components\n const filterDropdowns = hasFilters\n ? schema\n .filters!.map((filter) => {\n return ` <Popover open={${filter.field}ComboboxOpen} onOpenChange={set${toPascalCase(filter.field)}ComboboxOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={${filter.field}ComboboxOpen}\n className=\"w-[200px] justify-between\"\n >\n {${filter.field} || '${filter.label}'}\n <ChevronsUpDown className=\"ml-2 h-4 w-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(filter.field)}('')\n })\n set${toPascalCase(filter.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-4 w-4',\n ${filter.field} === '' ? 'opacity-100' : 'opacity-0'\n )}\n />\n All ${filter.label}\n </CommandItem>\n {${filter.field}Options?.map((option) => (\n <CommandItem\n key={option}\n value={option}\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(filter.field)}(option)\n })\n set${toPascalCase(filter.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-4 w-4',\n ${filter.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 form component with submit button\n const searchInput = ` <form action={searchAction} className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"text-muted-foreground 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\"\n />\n </div>\n <SearchButton />\n </form>`\n\n const content = `${imports}\n${searchButtonComponent}interface ${pascalPlural}PageContentProps<TValue> {\n columns: ColumnDef<${pascalSingular}Data, TValue>[]\n}\n\nexport function ${pascalPlural}PageContent<TValue>({\n columns\n}: ${pascalPlural}PageContentProps<TValue>) {\n${queryClientLogic}\n${searchLogic}${deleteLogic}\n return (\n <>\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader title=\"${schema.label}\" description=\"${schema.description}\" />\n <div className=\"flex items-center gap-2\">\n${filterDropdowns ? `${filterDropdowns}\\n` : ''}${searchInput}\n${deleteButton}\n${createButton}\n </div>\n </div>\n\n <main className=\"space-y-6 p-6\">\n <${pascalPlural}Table ${tableProps} />\n </main>\n </>\n )\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${fileName}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toCamelCase,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate table component\n */\nexport async function generateTable(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const camelPlural = toCamelCase(pluralName)\n const camelSingular = toCamelCase(singularName)\n const tableFileName = `${toKebabCase(pluralName)}-table.tsx`\n const tableFilePath = path.join(adminDir, tableFileName)\n\n // Check if file exists\n if (fs.existsSync(tableFilePath) && !options.force) {\n console.warn(` ⚠️ Table file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${tableFileName}`\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\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 {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '${ir.adminUi}'\nimport { use${pascalPlural} } from '${ir.hooks}'\nimport { bulkUpdate${pascalPlural}SortOrder } from '${ir.actions(schema.name)}'\nimport type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\nimport '${ir.tableMeta}'\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 ${pascalPlural}TableProps<TValue> {\n columns: ColumnDef<${pascalSingular}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string${allFilterProps}\n}\n\nexport function ${pascalPlural}Table<TValue>({ columns, selectedIds, setSelectedIds, ${allParams} }: ${pascalPlural}TableProps<TValue>) {\n const { data, error, isPending } = use${pascalPlural}(${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<${pascalSingular}Data[]>([])\n const [hasChanges, setHasChanges] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n\n // Sync local data when server data changes or reorder mode is toggled\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 // Create array of { id, sortOrder } based on current order\n const updates = localData.map((item, index) => ({\n id: item.id as number,\n sortOrder: index\n }))\n\n const result = await bulkUpdate${pascalPlural}SortOrder(updates)\n\n if (result.success) {\n toast.success('Sort order saved successfully')\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\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 corner-squircle\">\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 fs.writeFileSync(tableFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${tableFileName}`\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { updateExports } from './exports'\nimport { getAvailableComponents, resolveRegistryDeps } from './registry'\nimport { extractFileName, transformSource } from './transform'\nimport {\n type AddComponentOptions,\n DEFAULT_TARGET,\n type RegistryItem,\n TARGET_CONFIGS\n} from './types'\n\nconst log = (message: string, silent = false) => {\n if (!silent) console.log(message)\n}\n\nconst runPnpmAdd = (deps: string[], packageFilter: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['add', ...deps, '--filter', packageFilter], {\n stdio: 'inherit',\n shell: true\n })\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n } else {\n reject(new Error(`pnpm add failed with code ${code}`))\n }\n })\n\n child.on('error', reject)\n })\n}\n\nconst runLintFix = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['lint:fix'], {\n stdio: 'inherit',\n shell: true\n })\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n } else {\n // Don't fail on lint errors, just warn\n console.warn('Lint fix completed with warnings')\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport const listComponents = async (): Promise<void> => {\n console.log('Fetching available components...\\n')\n const components = await getAvailableComponents()\n console.log('Available shadcn components:\\n')\n console.log(components.map((c) => ` - ${c}`).join('\\n'))\n console.log(`\\nTotal: ${components.length} components`)\n}\n\nexport const addComponents = async (\n componentNames: string[],\n options: AddComponentOptions = {}\n): Promise<void> => {\n const {\n overwrite = false,\n silent = false,\n skipMissing = false,\n target = DEFAULT_TARGET\n } = options\n const { componentsDir: targetComponentsDir, packageFilter } = TARGET_CONFIGS[target]\n\n if (componentNames.length === 0) {\n throw new Error('No components specified')\n }\n\n log(`Resolving dependencies for: ${componentNames.join(', ')}`, silent)\n log(`Target package: ${packageFilter}`, silent)\n\n // Resolve all dependencies recursively\n const allComponents = await resolveRegistryDeps(componentNames, new Set(), { skipMissing })\n\n // Dedupe by name\n const componentMap = new Map<string, RegistryItem>()\n for (const component of allComponents) {\n componentMap.set(component.name, component)\n }\n\n const componentsToInstall = Array.from(componentMap.values())\n log(`\\nComponents to install: ${componentsToInstall.map((c) => c.name).join(', ')}`, silent)\n\n // Ensure components directory exists\n const componentsDir = resolve(process.cwd(), targetComponentsDir)\n if (!existsSync(componentsDir)) {\n mkdirSync(componentsDir, { recursive: true })\n }\n\n // Collect all npm dependencies\n const allDeps = new Set<string>()\n const allDevDeps = new Set<string>()\n const installedComponents: string[] = []\n\n // Write component files\n for (const component of componentsToInstall) {\n for (const file of component.files) {\n const fileName = extractFileName(file.path)\n const componentName = fileName.replace(/\\.(tsx?|ts)$/, '')\n const filePath = resolve(componentsDir, fileName)\n\n if (existsSync(filePath) && !overwrite) {\n log(` Skipping ${fileName} (already exists)`, silent)\n continue\n }\n\n const transformedContent = transformSource(file.content)\n writeFileSync(filePath, transformedContent)\n log(` Created ${fileName}`, silent)\n installedComponents.push(componentName)\n }\n\n // Collect dependencies\n if (component.dependencies) {\n for (const dep of component.dependencies) {\n allDeps.add(dep)\n }\n }\n if (component.devDependencies) {\n for (const dep of component.devDependencies) {\n allDevDeps.add(dep)\n }\n }\n }\n\n // Install npm dependencies\n if (allDeps.size > 0) {\n log(`\\nInstalling dependencies: ${Array.from(allDeps).join(', ')}`, silent)\n await runPnpmAdd(Array.from(allDeps), packageFilter)\n }\n\n // Update exports\n if (installedComponents.length > 0) {\n log('\\nUpdating component exports...', silent)\n updateExports(installedComponents, target)\n }\n\n // Run lint:fix\n log('\\nRunning lint:fix...', silent)\n await runLintFix()\n\n log(`\\nDone! Installed ${installedComponents.length} component(s).`, silent)\n}\n\nexport const addAllComponents = async (options: AddComponentOptions = {}): Promise<void> => {\n const { target = DEFAULT_TARGET } = options\n const { packageFilter } = TARGET_CONFIGS[target]\n console.log('Fetching all available components...')\n console.log(`Target package: ${packageFilter}`)\n const components = await getAvailableComponents()\n console.log(`Found ${components.length} components to install\\n`)\n await addComponents(components, { ...options, skipMissing: true })\n}\n","import { readFileSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { DEFAULT_TARGET, TARGET_CONFIGS, type TargetPackage } from './types'\n\nconst INDEX_FILE = 'index.ts'\n\n/**\n * Update the components index.ts to include exports for new components\n */\nexport const updateExports = (\n componentNames: string[],\n target: TargetPackage = DEFAULT_TARGET\n): void => {\n const { componentsDir } = TARGET_CONFIGS[target]\n const indexPath = resolve(process.cwd(), componentsDir, INDEX_FILE)\n\n let content: string\n try {\n content = readFileSync(indexPath, 'utf-8')\n } catch {\n content = ''\n }\n\n // Parse existing exports\n const existingExports = new Set<string>()\n const exportRegex = /export \\* from ['\"]\\.\\/([^'\"]+)['\"]/g\n const matches = content.matchAll(exportRegex)\n for (const match of matches) {\n existingExports.add(match[1])\n }\n\n // Add new exports\n for (const name of componentNames) {\n existingExports.add(name)\n }\n\n // Sort and generate new content\n const sortedExports = Array.from(existingExports).sort()\n const newContent = `${sortedExports.map((name) => `export * from './${name}'`).join('\\n')}\\n`\n\n writeFileSync(indexPath, newContent)\n}\n\n/**\n * Check if an export already exists\n */\nexport const exportExists = (\n componentName: string,\n target: TargetPackage = DEFAULT_TARGET\n): boolean => {\n const { componentsDir } = TARGET_CONFIGS[target]\n const indexPath = resolve(process.cwd(), componentsDir, INDEX_FILE)\n\n let content: string\n try {\n content = readFileSync(indexPath, 'utf-8')\n } catch {\n return false\n }\n\n return content.includes(`from './${componentName}'`)\n}\n","export interface RegistryFile {\n path: string\n content: string\n type?: string\n target?: string\n}\n\nexport interface RegistryItem {\n name: string\n type: string\n dependencies?: string[]\n devDependencies?: string[]\n registryDependencies?: string[]\n files: RegistryFile[]\n cssVars?: Record<string, Record<string, string>>\n tailwind?: {\n config?: Record<string, unknown>\n }\n}\n\nexport interface RegistryIndexItem {\n name: string\n type: string\n registryDependencies?: string[]\n dependencies?: string[]\n files?: Array<{ path: string; type: string }>\n}\n\nexport type RegistryIndex = RegistryIndexItem[]\n\nexport interface AddComponentOptions {\n overwrite?: boolean\n silent?: boolean\n skipMissing?: boolean\n target?: TargetPackage\n}\n\nexport type TargetPackage = 'web-ui' | 'admin-ui'\n\nexport interface TargetConfig {\n componentsDir: string\n packageFilter: string\n}\n\nexport const TARGET_CONFIGS: Record<TargetPackage, TargetConfig> = {\n 'web-ui': {\n componentsDir: 'packages/web-ui/src/components',\n packageFilter: '@betterstart/web-ui'\n },\n 'admin-ui': {\n componentsDir: 'packages/admin-ui/src/components',\n packageFilter: '@betterstart/admin-ui'\n }\n}\n\nexport const DEFAULT_TARGET: TargetPackage = 'web-ui'\n","import type { RegistryIndex, RegistryItem } from './types'\n\nconst REGISTRY_BASE = 'https://ui.shadcn.com/r/styles/new-york'\nconst INDEX_URL = 'https://ui.shadcn.com/r/index.json'\n\nexport const fetchComponent = async (name: string): Promise<RegistryItem> => {\n const res = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (!res.ok) {\n throw new Error(`Component \"${name}\" not found in registry (status: ${res.status})`)\n }\n return res.json() as Promise<RegistryItem>\n}\n\nexport const tryFetchComponent = async (name: string): Promise<RegistryItem | null> => {\n const res = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (!res.ok) {\n return null\n }\n return res.json() as Promise<RegistryItem>\n}\n\nexport const fetchIndex = async (): Promise<RegistryIndex> => {\n const res = await fetch(INDEX_URL)\n if (!res.ok) {\n throw new Error(`Failed to fetch registry index (status: ${res.status})`)\n }\n return res.json() as Promise<RegistryIndex>\n}\n\nexport const resolveRegistryDeps = async (\n names: string[],\n seen = new Set<string>(),\n options: { skipMissing?: boolean } = {}\n): Promise<RegistryItem[]> => {\n const items: RegistryItem[] = []\n const { skipMissing = false } = options\n\n for (const name of names) {\n if (seen.has(name)) continue\n seen.add(name)\n\n let item: RegistryItem | null\n if (skipMissing) {\n item = await tryFetchComponent(name)\n if (!item) {\n console.warn(` Skipping \"${name}\" (not found in registry)`)\n continue\n }\n } else {\n item = await fetchComponent(name)\n }\n\n // First resolve dependencies recursively\n if (item.registryDependencies?.length) {\n const deps = await resolveRegistryDeps(item.registryDependencies, seen, options)\n items.push(...deps)\n }\n\n items.push(item)\n }\n\n return items\n}\n\nexport const getAvailableComponents = async (): Promise<string[]> => {\n const index = await fetchIndex()\n return index\n .filter((item) => item.type === 'registry:ui')\n .map((item) => item.name)\n .sort()\n}\n","/**\n * Transform shadcn component source code for project compatibility\n */\nexport const transformSource = (content: string): string => {\n let result = content\n\n // Replace @/lib/utils import with @betterstart/utils\n result = result.replace(/from\\s+[\"']@\\/lib\\/utils[\"']/g, 'from \"@betterstart/utils\"')\n\n // Replace relative lib/utils imports\n result = result.replace(/from\\s+[\"']\\.\\.?\\/lib\\/utils[\"']/g, 'from \"@betterstart/utils\"')\n\n // Replace @/components/ui imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/components\\/ui\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/hooks imports with @betterstart/hooks\n result = result.replace(/from\\s+[\"']@\\/hooks\\/([^\"']+)[\"']/g, 'from \"@betterstart/hooks\"')\n\n // Replace @/registry/new-york/ui imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/registry\\/new-york\\/ui\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/registry/new-york/hooks imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/registry\\/new-york\\/hooks\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/registry/new-york/lib/utils import with @betterstart/utils\n result = result.replace(\n /from\\s+[\"']@\\/registry\\/new-york\\/lib\\/utils[\"']/g,\n 'from \"@betterstart/utils\"'\n )\n\n // Fix react-resizable-panels v4.x API changes (PanelGroup -> Group, PanelResizeHandle -> Separator)\n result = result.replace(/ResizablePrimitive\\.PanelGroup/g, 'ResizablePrimitive.Group')\n result = result.replace(/ResizablePrimitive\\.PanelResizeHandle/g, 'ResizablePrimitive.Separator')\n\n return result\n}\n\n/**\n * Extract the component file name from registry path\n */\nexport const extractFileName = (registryPath: string): string => {\n // Registry paths are like \"ui/button.tsx\" -> extract \"button.tsx\"\n const parts = registryPath.split('/')\n return parts[parts.length - 1]\n}\n","// Main entry point for the codegen package\n\n// Re-export config helpers for use in betterstart.config.ts\nexport { defineConfig } from './config/loader'\nexport type { UserConfig } from './config/types'\nexport * from './generators'\nexport * from './shadcn'\nexport * from './types'\nexport * from './utils'\n\n// Re-export key functions for programmatic use\nimport { execSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { findProjectRoot, loadConfig, resolveConfig } from './config'\nimport {\n generateActions,\n generateCache,\n generateColumns,\n generateCreatePage,\n generateDatabase,\n generateEditPage,\n generateForm,\n generateHook,\n generatePage,\n generatePageContent,\n generateTable,\n updateNavigation\n} from './generators'\nimport { flattenFields } from './generators/shared-utils'\nimport type { GeneratorOptions, Schema } from './types'\nimport { initImportResolver, initPaths } from './utils'\n\n/**\n * Validate the schema structure\n */\nexport function validateSchema(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\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\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') {\n continue\n }\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // Validate columns\n const flattenedFields = flattenFields(schema.fields || [])\n const fieldNames = new Set(flattenedFields.map((f) => f.name))\n\n // Add special fields that might be used in columns but not in schema fields\n fieldNames.add('id') // ID is always available\n fieldNames.add('createdAt') // Timestamps are auto-added\n fieldNames.add('updatedAt')\n fieldNames.add('published') // Published is auto-added for draft mode\n fieldNames.add('submittedAt') // Submission timestamp for form submissions\n fieldNames.add('ipAddress') // IP address for form submissions\n fieldNames.add('userAgent') // User agent for form submissions\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 name. Available fields: ${Array.from(fieldNames).join(', ')}`\n )\n }\n }\n\n return errors\n}\n\n/**\n * Main generator function - generates all files for a schema\n */\nexport async function generate(schemaName: string, options: GeneratorOptions = {}): Promise<void> {\n // Initialize paths (auto-detects monorepo root)\n const paths = initPaths()\n\n // Load config and initialize import resolver\n const projectRoot = findProjectRoot(process.cwd())\n const config = await loadConfig(projectRoot)\n const resolvedConfig = resolveConfig(config, projectRoot)\n initImportResolver(resolvedConfig)\n\n const schemaPath = path.join(paths.schemas, `${schemaName}.json`)\n\n console.log('\\n🚀 Admin Codemod Generator\\n')\n console.log(`📁 Monorepo root: ${paths.root}`)\n console.log(`📄 Reading schema: ${schemaName}.json`)\n\n // Check if schema file exists\n if (!fs.existsSync(schemaPath)) {\n console.error(`❌ Schema file not found: ${schemaPath}`)\n process.exit(1)\n }\n\n // Read and parse schema\n let schema: Schema\n try {\n const schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n schema = JSON.parse(schemaContent)\n } catch (error) {\n console.error(`❌ Failed to parse schema file: ${error}`)\n process.exit(1)\n }\n\n // Validate schema\n console.log('✓ Schema loaded')\n console.log('🔍 Validating schema...')\n const validationErrors = validateSchema(schema)\n if (validationErrors.length > 0) {\n console.error('\\n❌ 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')\n\n // Track generated files\n const generatedFiles: string[] = []\n\n try {\n console.log('\\n📦 Generating files...\\n')\n\n // Generate database schema and migration\n if (!options.skipMigration) {\n console.log('1️⃣ Generating database schema...')\n const dbFiles = await generateDatabase(schema, options)\n generatedFiles.push(...dbFiles)\n console.log(' ✓ Database schema generated')\n }\n\n // Generate server actions\n console.log('2️⃣ Generating server actions...')\n const actionsFile = await generateActions(schema, options)\n generatedFiles.push(actionsFile)\n console.log(' ✓ Server actions generated')\n\n // Generate React Query hook\n console.log('3️⃣ Generating React Query hook...')\n const hookFile = await generateHook(schema, options)\n generatedFiles.push(hookFile)\n console.log(' ✓ Hook generated')\n\n // Generate columns\n console.log('4️⃣ Generating table columns...')\n const columnsFile = await generateColumns(schema, options)\n generatedFiles.push(columnsFile)\n console.log(' ✓ Columns generated')\n\n // Generate table component\n console.log('5️⃣ Generating table component...')\n const tableFile = await generateTable(schema, options)\n generatedFiles.push(tableFile)\n console.log(' ✓ Table component generated')\n\n // Generate page content component\n console.log('6️⃣ Generating page content component...')\n const pageContentFile = await generatePageContent(schema, options)\n generatedFiles.push(pageContentFile)\n console.log(' ✓ Page content component generated')\n\n // Generate page component\n console.log('7️⃣ Generating page component...')\n const pageFile = await generatePage(schema, options)\n generatedFiles.push(pageFile)\n console.log(' ✓ Page component generated')\n\n // Generate form and CRUD pages if actions are enabled\n if (schema.actions?.create || schema.actions?.edit) {\n console.log('8️⃣ Generating form component...')\n const formFile = await generateForm(schema, options)\n generatedFiles.push(formFile)\n console.log(' ✓ Form component generated')\n\n if (schema.actions?.create) {\n console.log('9️⃣ Generating create page...')\n const createPageFile = await generateCreatePage(schema, options)\n generatedFiles.push(createPageFile)\n console.log(' ✓ Create page generated')\n }\n\n if (schema.actions?.edit) {\n console.log('🔟 Generating edit page...')\n const editPageFile = await generateEditPage(schema, options)\n generatedFiles.push(editPageFile)\n console.log(' ✓ Edit page generated')\n }\n }\n\n // Update navigation\n console.log('1️⃣1️⃣ Updating navigation...')\n await updateNavigation(schema, options)\n generatedFiles.push('packages/data/src/admin/navigation.ts')\n console.log(' ✓ Navigation updated')\n\n // Generate cache module (tags, cached-queries, revalidate)\n console.log('1️⃣2️⃣ Generating cache module...')\n const cacheFiles = await generateCache(schema, options)\n generatedFiles.push(...cacheFiles)\n console.log(' ✓ Cache module generated')\n\n // Success summary\n console.log('\\n✅ Generation complete!\\n')\n console.log('📁 Generated files:')\n for (const file of generatedFiles) {\n console.log(` - ${file}`)\n }\n\n // Run database migrations if not skipped\n if (!options.skipMigration) {\n console.log('\\n🗄️ Running database migrations...')\n\n // Check if DATABASE_URL is configured\n if (!process.env.DATABASE_URL) {\n console.warn('\\n⚠️ DATABASE_URL environment variable not found')\n console.warn(' Skipping database migration')\n console.warn(' To run migrations later:')\n console.warn(' 1. Configure DATABASE_URL in your .env file')\n console.warn(' 2. Run: pnpm db:push')\n } else {\n try {\n execSync('pnpm db:push', {\n cwd: paths.root,\n stdio: 'inherit'\n })\n console.log('\\n ✓ Database schema synced')\n } catch (error) {\n console.error('\\n⚠️ Database migration failed')\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n // Check for common migration errors and provide helpful guidance\n if (errorMessage.includes('value too long for type character varying')) {\n console.error(\n '\\n 💡 This error occurs when existing data exceeds varchar(255) limits.'\n )\n console.error(' Solution: Run a migration to alter columns to TEXT type:')\n console.error(' 1. Create a migration file in packages/database/drizzle/')\n console.error(' 2. Add: ALTER TABLE \"TableName\" ALTER COLUMN \"columnName\" TYPE text;')\n console.error(' 3. Run: pnpm db:migrate')\n console.error(' Or manually run the ALTER TABLE command in your database.')\n } else {\n console.error(' You can run manually: pnpm db:push')\n }\n console.error(` Error: ${errorMessage}`)\n }\n }\n }\n\n // Run linter and formatter as final step\n console.log('\\n🎨 Running formatter and linter...')\n try {\n execSync('pnpm lint:fix', {\n cwd: paths.root,\n stdio: 'pipe'\n })\n console.log(' ✓ Code formatted and linted with Biome')\n } catch (_error) {\n console.warn(' ⚠️ Linter encountered issues (this is usually fine)')\n console.warn(' You can run: pnpm lint:fix manually if needed')\n }\n\n console.log('\\n📝 Next steps:')\n console.log(' 1. Review the generated files')\n if (options.skipMigration) {\n console.log(' 2. Run migrations: pnpm db:push')\n console.log(` 3. Start the dev server and visit /admin/${schema.name}`)\n } else {\n console.log(` 2. Start the dev server and visit /admin/${schema.name}`)\n }\n console.log('')\n } catch (error) {\n console.error('\\n❌ Generation failed:', error)\n process.exit(1)\n }\n}\n"],"mappings":"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","names":["relationshipFields","hasRelationships","path","fs","path","fs","path","fs","path","path","fs","fs","path","path","fs","fs","path","getManyToManyFields","path","fs","fs","path","path","fs","fs","path","flattenFields","path","fs","fs","path","base","toPascalCase","path","fs","options","wrapWithShowWhen","stringLikeTypes","fs","path","hasDynamicFields","getAllFields","flattenFields","path","fs","fs","path","fs","path","path","fs","hasDynamicFields","getAllFields","flattenFields","getAllFields","hasDynamicFields","path","fs","match","generateForm","execSync","fs","path","path","fs","fs","path","parseNavigationFile","parseNavigationItem","parseSubItems","generateNavigationCode","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","writeFileSync","resolve","resolve","writeFileSync","fs","path","path","fs"]}
1
+ {"version":3,"sources":["../src/generators/actions.ts","../src/generators/shared-utils.ts","../src/generators/cache.ts","../src/generators/columns.ts","../src/generators/create-page.ts","../src/generators/database.ts","../src/generators/edit-page.ts","../src/generators/email-template.ts","../src/generators/form.ts","../src/generators/form-admin-pages.ts","../src/generators/form-generator.ts","../src/generators/form-navigation.ts","../src/generators/hook.ts","../src/generators/navigation.ts","../src/generators/page.ts","../src/generators/page-content.ts","../src/generators/table.ts","../src/shadcn/add-component.ts","../src/shadcn/exports.ts","../src/shadcn/types.ts","../src/shadcn/registry.ts","../src/shadcn/transform.ts","../src/index.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Extract many-to-many relationship fields from schema\n */\nfunction getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n return flattenFields(fields).filter(\n (f) => f.type === 'relationship' && f.multiple === true && f.relationship\n )\n}\n\n/**\n * Get all nested relationship fields (recursively checks nested fields including lists)\n */\nfunction _getNestedRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const relationships: SchemaField[] = []\n\n function checkFields(fieldsToCheck: SchemaField[]): void {\n for (const field of fieldsToCheck) {\n // Collect relationship fields (excluding many-to-many)\n if (field.type === 'relationship' && field.relationship && !field.multiple) {\n relationships.push(field)\n }\n // Check nested fields in lists\n if (field.type === 'list' && field.fields && field.fields.length > 0) {\n checkFields(field.fields)\n }\n // Check nested fields in groups\n if (field.type === 'group' && field.fields && field.fields.length > 0) {\n checkFields(field.fields)\n }\n // Check fields in tabs\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields) {\n checkFields(tab.fields)\n }\n }\n }\n }\n }\n\n checkFields(fields)\n return relationships\n}\n\n/**\n * Generate slugify helper function\n */\nfunction generateSlugifyHelper(): string {\n return `\n/**\n * Convert text to URL-friendly slug\n * - Removes special characters\n * - Converts to lowercase\n * - Replaces spaces with dashes\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^\\\\w\\\\s-]/g, '') // Remove special chars\n .replace(/\\\\s+/g, '-') // Replace spaces with dashes\n .replace(/-+/g, '-') // Replace multiple dashes with single dash\n .replace(/^-+|-+$/g, '') // Trim dashes from start/end\n}\n`\n}\n\n/**\n * Generate field mapping with proper null handling\n */\nfunction generateFieldMapping(field: SchemaField, source: string = 'input'): string {\n if (field.type === 'list') {\n return `${source}.${field.name} || []`\n }\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 // Handle optional string/varchar/select fields - convert undefined/empty to null\n if (\n !field.required &&\n (field.type === 'string' ||\n field.type === 'varchar' ||\n field.type === 'text' ||\n field.type === 'select')\n ) {\n return `${source}.${field.name} && ${source}.${field.name} !== '' ? ${source}.${field.name} : null`\n }\n return `${source}.${field.name}`\n}\n\n/**\n * Generate TypeScript type for a field\n * @param field - The field to generate a type for\n * @param forInputOutput - 'input' for create/update inputs (IDs as strings),\n * 'output' for main data interface (full nested objects),\n * 'nested' for fields within a relationship (IDs as strings, no nested Data types)\n * @param schemasPath - Optional path to schemas directory (required for 'output' mode with relationships)\n */\nfunction getFieldType(\n field: SchemaField,\n forInputOutput: 'input' | 'output' | 'nested' = 'output',\n schemasPath?: string\n): 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 'date':\n case 'time':\n case 'timestamp':\n case 'image':\n return 'string'\n case 'relationship':\n // For input or nested, relationships are stored as IDs (strings)\n // For output, return the full related object with inline type (to handle nested relationships correctly)\n if (forInputOutput === 'input' || forInputOutput === 'nested') {\n return 'string'\n }\n if (field.relationship && schemasPath) {\n // Generate inline type for relationship to handle nested relationships correctly\n const inlineType = generateNestedRelationshipType(field.relationship, schemasPath)\n if (inlineType) {\n return `${inlineType} | null`\n }\n }\n // Fallback to simple Data type import if no schemasPath or failed to load schema\n if (field.relationship) {\n const relationshipSingular = singularize(field.relationship)\n const relationshipPascal = toPascalCase(relationshipSingular)\n return `${relationshipPascal}Data | null`\n }\n return 'string'\n case 'group':\n // Groups are stored as nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .map((f) => {\n const type = getFieldType(f, forInputOutput, schemasPath)\n return `${quotePropertyName(f.name)}?: ${type}`\n })\n .join('; ')\n return `{ ${nestedType} }`\n }\n return 'Record<string, unknown>'\n case 'list':\n // If list has nested fields, return array of objects\n if (field.fields && field.fields.length > 0) {\n const nestedType = field.fields\n .flatMap((f) => {\n // For input types, relationships are stored as IDs (strings) in JSONB\n // For output types, relationships should be full objects\n const mode = forInputOutput === 'input' ? 'input' : 'output'\n const type = getFieldType(f, mode, schemasPath)\n const fields = [`${quotePropertyName(f.name)}?: ${type}`]\n // Add icon field if hasIcon is true\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 // Curriculum stores both items and weeks - mode determines which editor to show\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 * Generate an inline type for a nested relationship field\n * Includes commonly needed fields from the related schema\n */\nfunction generateNestedRelationshipType(\n relationshipName: string,\n schemasPath: string\n): string | null {\n const relSchemaPath = path.join(schemasPath, `${relationshipName}.json`)\n if (!fs.existsSync(relSchemaPath)) {\n return null\n }\n\n try {\n const relSchemaContent = fs.readFileSync(relSchemaPath, 'utf-8')\n const relSchema = JSON.parse(relSchemaContent) as Schema\n const relDbFields = flattenFields(relSchema.fields).filter(\n (f) => !f.primaryKey && f.type !== 'tabs' && f.type !== 'group' && f.type !== 'separator'\n )\n\n const fieldTypes: string[] = ['id: number | null']\n\n // Include all database fields from the related schema\n for (const field of relDbFields) {\n const type = getFieldType(field, 'nested')\n const nullSuffix = field.required ? '' : ' | null'\n fieldTypes.push(`${quotePropertyName(field.name)}: ${type}${nullSuffix}`)\n }\n\n // Always include auto-generated database fields (they exist on every table but aren't in schema.fields)\n if (!relDbFields.some((f) => f.name === 'createdAt')) fieldTypes.push('createdAt: string')\n if (!relDbFields.some((f) => f.name === 'updatedAt')) fieldTypes.push('updatedAt: string')\n if (!relDbFields.some((f) => f.name === 'sortOrder')) fieldTypes.push('sortOrder: number')\n\n return `{ ${fieldTypes.join('; ')} }`\n } catch {\n return null\n }\n}\n\n/**\n * Generate dummy data value for a field\n */\nfunction _generateDummyValue(field: SchemaField, index: number): string {\n switch (field.type) {\n case 'serial':\n return `${index + 1}`\n case 'number':\n case 'decimal':\n if (field.name.toLowerCase().includes('price')) {\n return `${(index + 1) * 10}.99`\n }\n return `${index + 1}`\n case 'boolean':\n return index % 2 === 0 ? 'true' : 'false'\n case 'string':\n case 'varchar':\n case 'text':\n case 'markdown':\n if (field.name.toLowerCase().includes('email')) {\n return `'user${index + 1}@example.com'`\n }\n if (field.name.toLowerCase().includes('name')) {\n return `'${field.label || field.name} ${index + 1}'`\n }\n if (field.name.toLowerCase().includes('description')) {\n return `'Description for item ${index + 1}'`\n }\n return `'Sample ${field.name} ${index + 1}'`\n case 'timestamp':\n case 'date':\n return `new Date('2025-01-${String(index + 1).padStart(2, '0')}').toISOString()`\n case 'time':\n return `'${String(9 + index).padStart(2, '0')}:00:00'`\n case 'list':\n // If list has nested fields, generate array of objects\n if (field.fields && field.fields.length > 0) {\n const nestedObject = field.fields\n .map((f) => {\n const value = _generateDummyValue(f, 0)\n return `${f.name}: ${value}`\n })\n .join(', ')\n return `[{ ${nestedObject} }, { ${nestedObject.replace(/1/g, '2')} }]`\n }\n return `['Item 1', 'Item 2', 'Item 3']`\n case 'image':\n return `'https://via.placeholder.com/150'`\n default:\n return `'Value ${index + 1}'`\n }\n}\n\n/**\n * Generate server actions file in packages/lib/src/actions/\n */\nexport async function generateActions(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const actionsDir = path.join(paths.lib, 'src/actions')\n ensureDir(actionsDir)\n\n const actionsFilePath = path.join(actionsDir, `${schema.name}.ts`)\n\n // Check if file exists\n if (fs.existsSync(actionsFilePath) && !options.force) {\n console.warn(` ⚠️ Actions file already exists: ${schema.name}.ts. Use --force to overwrite.`)\n return `packages/lib/src/actions/${schema.name}.ts`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const tableVariableName = toCamelCase(schema.name)\n\n // Flatten fields to handle groups\n const dbFields = flattenFields(schema.fields)\n\n // Collect many-to-many relationship fields\n const m2mFields = getManyToManyFields(schema.fields)\n const hasM2MRelationships = m2mFields.length > 0\n\n // Collect single-value relationship fields (exclude many-to-many)\n const relationshipFields = dbFields.filter(\n (f) => f.type === 'relationship' && f.relationship && !f.multiple\n )\n\n // Filter out M2M fields from dbFields for regular processing\n const regularDbFields = dbFields.filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n // Check if schema has a slug field\n const hasSlugField = regularDbFields.some((f) => f.name === 'slug')\n\n // Check for draft mode - automatically add published field if not present\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = regularDbFields.some((f) => f.name === 'published')\n\n // Add published field for draft mode if not already present\n const allDbFields =\n hasDraftMode && !hasPublishedField\n ? [...regularDbFields, { name: 'published', type: 'boolean' as const, required: true }]\n : [...regularDbFields]\n\n // Automatically add createdAt and updatedAt if not present\n const hasCreatedAt = regularDbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = regularDbFields.some((f) => f.name === 'updatedAt')\n if (!hasCreatedAt) {\n allDbFields.push({ name: 'createdAt', type: 'timestamp' as const, required: true })\n }\n if (!hasUpdatedAt) {\n allDbFields.push({ name: 'updatedAt', type: 'timestamp' as const, required: true })\n }\n\n // Add sortOrder field for row reordering\n const hasSortOrder = regularDbFields.some((f) => f.name === 'sortOrder')\n if (!hasSortOrder) {\n allDbFields.push({ name: 'sortOrder', type: 'number' as const, required: true })\n }\n\n // Generate M2M field types for interfaces (as arrays of IDs)\n const m2mFieldTypes = m2mFields.map((f) => ` ${quotePropertyName(f.name)}: number[]`).join('\\n')\n\n // Generate optional HTML fields for markdown fields (for pre-rendered HTML content)\n const markdownHtmlFields = allDbFields\n .filter((f) => f.type === 'markdown')\n .map((f) => ` ${quotePropertyName(`${f.name}Html`)}?: string`)\n .join('\\n')\n\n // Generate TypeScript interfaces\n // Pass paths.schemas so relationship fields can generate proper inline types with nested relationships as strings\n const dataInterface = `export interface ${pascalSingular}Data {\n${allDbFields.map((f) => ` ${quotePropertyName(f.name)}: ${getFieldType(f, 'output', paths.schemas)}${f.required ? '' : ' | null'}`).join('\\n')}${markdownHtmlFields ? `\\n${markdownHtmlFields}` : ''}${m2mFieldTypes ? `\\n${m2mFieldTypes}` : ''}\n}`\n\n const responseInterface = `export interface ${pascalPlural}Response {\n ${toCamelCase(pluralName)}: ${pascalSingular}Data[]\n total: number\n}`\n\n // Generate filter interface with search and filterable fields\n // Use allDbFields to include auto-added fields like published (for draft mode)\n const filterableFields = allDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'sortOrder' &&\n ['string', 'varchar', 'text', 'boolean', 'number', 'decimal'].includes(f.type)\n )\n const filtersInterface = `export interface Get${pascalPlural}Filters {\n search?: string\n${filterableFields.map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f)}`).join('\\n')}\n limit?: number\n}`\n\n // Generate CreateInput interface (exclude auto-generated fields, but include published when draft mode)\n // Use regularDbFields to exclude M2M relationship fields (they're handled via junction tables)\n const createFields = regularDbFields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'sortOrder' // sortOrder is auto-calculated on insert\n // Note: published is included when draft mode is enabled so users can choose to publish on create\n )\n const createInterface = `export interface Create${pascalSingular}Input {\n${createFields.map((f) => ` ${quotePropertyName(f.name)}${f.required ? '' : '?'}: ${getFieldType(f, 'input')}`).join('\\n')}${\n hasDraftMode ? `\\n published?: boolean` : ''\n}\n}`\n\n const createResultInterface = `export interface Create${pascalSingular}Result {\n success: boolean\n error?: string\n ${toCamelCase(singularName)}?: ${pascalSingular}Data\n}`\n\n // Generate UpdateInput interface\n const updateInterface = `export interface Update${pascalSingular}Input {\n id: number\n${createFields.map((f) => ` ${quotePropertyName(f.name)}?: ${getFieldType(f, 'input')}`).join('\\n')}${\n hasDraftMode ? `\\n published?: boolean` : ''\n}\n}`\n\n const updateResultInterface = `export interface Update${pascalSingular}Result {\n success: boolean\n error?: string\n ${toCamelCase(singularName)}?: ${pascalSingular}Data\n}`\n\n const deleteResultInterface = `export interface Delete${pascalSingular}Result {\n success: boolean\n error?: string\n}`\n\n // Determine search fields from schema\n const searchFields = schema.search?.fields || []\n const hasSearch = searchFields.length > 0\n\n // Generate relationship joins and selects\n const hasRelationships = relationshipFields.length > 0\n const relationshipJoins = hasRelationships\n ? relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n return `.leftJoin(${relTable}, sql\\`CAST(NULLIF(\\${${tableVariableName}.${f.name}}, '') AS INTEGER) = \\${${relTable}.id}\\`)`\n })\n .join('')\n : ''\n\n // Helper to load related schema and get its database fields\n // Only returns id, slug, title, name (whichever exist in the related schema)\n const getRelatedSchemaFields = (relationshipName: string): string[] => {\n const relSchemaPath = path.join(paths.schemas, `${relationshipName}.json`)\n if (fs.existsSync(relSchemaPath)) {\n try {\n const relSchemaContent = fs.readFileSync(relSchemaPath, 'utf-8')\n const relSchema = JSON.parse(relSchemaContent) as Schema\n const relDbFields = flattenFields(relSchema.fields).filter(\n (f) => !f.primaryKey && f.type !== 'tabs' && f.type !== 'group' && f.type !== 'separator'\n )\n\n // Include all database fields from the related schema\n const fieldNames = ['id']\n for (const field of relDbFields) {\n fieldNames.push(field.name)\n }\n\n // Always include auto-generated database fields (they exist on every table but aren't in schema.fields)\n if (!relDbFields.some((f) => f.name === 'createdAt')) fieldNames.push('createdAt')\n if (!relDbFields.some((f) => f.name === 'updatedAt')) fieldNames.push('updatedAt')\n if (!relDbFields.some((f) => f.name === 'sortOrder')) fieldNames.push('sortOrder')\n\n return fieldNames\n } catch {\n // Fall back to minimal fields if schema can't be loaded\n return ['id']\n }\n }\n // Fall back to minimal fields if schema doesn't exist\n return ['id']\n }\n\n const relationshipSelects = hasRelationships\n ? relationshipFields\n .map((f) => {\n const relTable = toCamelCase(f.relationship!)\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldSelects = relFields\n .map((fieldName) => ` ${fieldName}: ${relTable}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: {\n${fieldSelects}\n },`\n })\n .join('\\n')\n : ''\n\n const allFieldsSelect = allDbFields\n .filter((f) => f.type !== 'relationship')\n .map((f) => ` ${f.name}: ${tableVariableName}.${f.name},`)\n .join('\\n')\n\n const selectClause = hasRelationships\n ? `db.select({\n${allFieldsSelect}\n${relationshipSelects}\n })\n .from(${tableVariableName})${relationshipJoins}`\n : `db.select().from(${tableVariableName})`\n\n // Helper function to get relationship fields inside a list field\n const getListRelationshipFields = (field: SchemaField): SchemaField[] => {\n if (field.type !== 'list' || !field.fields) {\n return []\n }\n return field.fields.filter((f) => f.type === 'relationship' && f.relationship)\n }\n\n // Helper function to convert nested list field types\n const generateListFieldConverter = (field: SchemaField): string => {\n if (field.type !== 'list' || !field.fields || field.fields.length === 0) {\n return `row.${field.name}`\n }\n\n const hasBooleanFields = field.fields.some((f) => f.type === 'boolean')\n const hasGroupFields = field.fields.some((f) => f.type === 'group')\n const relationshipFields = getListRelationshipFields(field)\n const hasRelationships = relationshipFields.length > 0\n\n if (!hasBooleanFields && !hasRelationships && !hasGroupFields) {\n return `row.${field.name}`\n }\n\n const conversions = field.fields\n .map((f) => {\n if (f.type === 'boolean') {\n return ` ${f.name}: typeof item.${f.name} === 'string' ? item.${f.name} === 'true' : (item.${f.name} as boolean | undefined)`\n }\n if (f.type === 'relationship' && f.relationship) {\n // Relationship fields in lists are stored as string IDs\n // They will be populated by a helper function after the query\n return ` ${f.name}: item.${f.name} as string | undefined`\n }\n if (f.type === 'group' && f.fields && f.fields.length > 0) {\n // Group fields are nested objects - cast to the correct type\n const groupType = f.fields\n .map(\n (gf) =>\n `${gf.name}?: ${gf.type === 'boolean' ? 'boolean' : gf.type === 'number' || gf.type === 'decimal' ? 'number' : 'string'}`\n )\n .join('; ')\n return ` ${f.name}: item.${f.name} as { ${groupType} } | undefined`\n }\n if (f.type === 'list') {\n // For nested lists, always map to ensure all schema fields are present\n // This handles cases where old data doesn't have all fields\n if (f.fields && f.fields.length > 0) {\n // Generate conversions for ALL fields in the nested list\n const allFieldConversions = f.fields\n .map((nf) => {\n if (nf.type === 'boolean') {\n const defaultVal = nf.default === true ? 'true' : 'false'\n return ` ${nf.name}: (typeof nestedItem.${nf.name} === 'string' ? nestedItem.${nf.name} === 'true' : (nestedItem.${nf.name} as boolean | null | undefined)) ?? ${defaultVal}`\n }\n // String-like fields: use stored value or undefined\n return ` ${nf.name}: (nestedItem.${nf.name} as string | null | undefined) ?? undefined`\n })\n .join(',\\n')\n\n return ` ${f.name}: (item.${f.name} as Array<Record<string, unknown>> | undefined)?.map((nestedItem) => ({\\n${allFieldConversions}\\n }))`\n }\n\n const nestedType =\n f.fields && f.fields.length > 0\n ? `Array<{ ${f.fields.map((nf) => `${nf.name}?: ${nf.type === 'boolean' ? 'boolean' : 'string'}`).join('; ')} }>`\n : 'Array<{ name?: string }>'\n return ` ${f.name}: item.${f.name} as ${nestedType} | undefined`\n }\n return ` ${f.name}: item.${f.name} as string | undefined`\n })\n .join(',\\n')\n\n return `row.${field.name}?.map((item: Record<string, unknown>) => ({\\n${conversions}\\n })) ?? row.${field.name}`\n }\n\n // Recursive function to find all list fields with relationships, including nested ones\n const findListFieldsWithRelationships = (\n fields: SchemaField[],\n parentPath: string[] = []\n ): Array<{ field: SchemaField; path: string[] }> => {\n const result: Array<{ field: SchemaField; path: string[] }> = []\n\n for (const field of fields) {\n if (field.type === 'list' && field.fields) {\n const currentPath = [...parentPath, field.name]\n const hasRelationships = field.fields.some(\n (nestedField) => nestedField.type === 'relationship' && nestedField.relationship\n )\n\n if (hasRelationships) {\n result.push({ field, path: currentPath })\n }\n\n // Recursively check nested lists\n const nestedLists = findListFieldsWithRelationships(field.fields, currentPath)\n result.push(...nestedLists)\n }\n }\n\n return result\n }\n\n const listFieldsWithRelationships = findListFieldsWithRelationships(allDbFields)\n\n const resultMapping = hasRelationships\n ? `\n\n const mapped${pascalPlural} = results.map((row) => ({\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship') {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}\n }))\n${\n listFieldsWithRelationships.length > 0\n ? `\n // Populate relationship fields in lists\n const populated${pascalPlural} = await Promise.all(\n mapped${pascalPlural}.map(record => populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data))\n )\n\n return {\n ${toCamelCase(pluralName)}: populated${pascalPlural},\n total: populated${pascalPlural}.length\n }`\n : `\n return {\n ${toCamelCase(pluralName)}: mapped${pascalPlural},\n total: mapped${pascalPlural}.length\n }`\n}`\n : listFieldsWithRelationships.length > 0\n ? `\n\n // Populate relationship fields in lists\n const populated${pascalPlural} = await Promise.all(\n results.map(record => populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data))\n )\n\n return {\n ${toCamelCase(pluralName)}: populated${pascalPlural},\n total: populated${pascalPlural}.length\n }`\n : `\n\n return {\n ${toCamelCase(pluralName)}: results as ${pascalSingular}Data[],\n total: results.length\n }`\n\n // Generate filter-based query builder\n const filterConditions = filterableFields\n .map((f) => {\n if (f.type === 'boolean') {\n return ` // Handle exact match for ${f.name}\n if (filters?.${f.name} !== undefined) {\n conditions.push(eq(${tableVariableName}.${f.name}, filters.${f.name}))\n }`\n }\n return ` if (filters?.${f.name}) {\n conditions.push(eq(${tableVariableName}.${f.name}, filters.${f.name}))\n }`\n })\n .join('\\n')\n\n const searchQueryBuilder = hasSearch\n ? `const conditions = []\n\n // Handle search query across multiple fields\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(${tableVariableName}.${f}, searchTerm)`).join(',\\n')}\n )\n )\n }\n\n // Handle exact match filters\n${filterConditions}\n\n const query = ${selectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${tableVariableName}.sortOrder))\n : query.orderBy(asc(${tableVariableName}.sortOrder))\n\n // Apply limit if specified (useful for build-time static generation)\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery`\n : `const conditions = []\n\n // Handle exact match filters\n${filterConditions}\n\n const query = ${selectClause}\n\n const orderedQuery = conditions.length > 0\n ? query.where(and(...conditions)).orderBy(asc(${tableVariableName}.sortOrder))\n : query.orderBy(asc(${tableVariableName}.sortOrder))\n\n // Apply limit if specified (useful for build-time static generation)\n const results = filters?.limit && filters.limit > 0\n ? await orderedQuery.limit(filters.limit)\n : await orderedQuery`\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n const filterFields = hasFilters && schema.filters ? schema.filters.map((f) => f.field) : []\n\n // Generate individual getDistinct functions for each filter field (Drizzle doesn't support dynamic field access)\n const getDistinctFunctions =\n hasFilters && filterFields.length > 0\n ? filterFields\n .map(\n (field) => `\nexport async function getDistinct${pascalPlural}${toPascalCase(field)}(): Promise<string[]> {\n try {\n const results = await db\n .selectDistinct({ value: ${tableVariableName}.${field} })\n .from(${tableVariableName})\n .where(isNotNull(${tableVariableName}.${field}))\n .orderBy(asc(${tableVariableName}.${field}))\n \n return results.map((r) => String(r.value)).filter(Boolean)\n } catch (error) {\n console.error('Error fetching distinct ${pluralName} ${field}:', error)\n return []\n }\n}`\n )\n .join('\\n')\n : ''\n\n // Generate helper function to populate relationship fields in lists\n // Collect all relationship field info for parallel query generation\n const allRelationshipQueries: Array<{\n fieldPath: string\n relField: SchemaField\n relTable: string\n relFieldsSelect: string\n listFieldName: string\n path: string[]\n parentField?: string\n }> = []\n\n for (const { field: listField, path } of listFieldsWithRelationships) {\n const relationshipFields = listField.fields!.filter(\n (f: SchemaField) => f.type === 'relationship' && f.relationship\n )\n\n for (const relField of relationshipFields) {\n const relTable = toCamelCase(relField.relationship!)\n const relFields = getRelatedSchemaFields(relField.relationship!)\n const relFieldsSelect = relFields.map((f) => `${f}: ${relTable}.${f}`).join(', ')\n const fieldPath = path.join('_')\n\n allRelationshipQueries.push({\n fieldPath,\n relField,\n relTable,\n relFieldsSelect,\n listFieldName: listField.name,\n path,\n parentField: path.length === 2 ? path[0] : undefined\n })\n }\n }\n\n const populateListRelationshipsFunction =\n listFieldsWithRelationships.length > 0\n ? `\n/**\n * Helper function to populate relationship fields inside list fields\n * Uses Promise.all for parallel query execution\n */\nasync function populate${pascalSingular}ListRelationships(record: ${pascalSingular}Data): Promise<${pascalSingular}Data> {\n // Phase 1: Collect all IDs (synchronous)\n${allRelationshipQueries\n .map((q) => {\n if (q.path.length === 1) {\n return ` const ${q.fieldPath}_${q.relField.name}Ids = record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})\n ? record.${q.listFieldName}\n .map((item: Record<string, unknown>) => item.${q.relField.name})\n .filter((id: unknown) => id != null && id !== '')\n .map((id: unknown) => Number.parseInt(String(id), 10))\n .filter((id: number) => !Number.isNaN(id))\n : []`\n }\n if (q.path.length === 2) {\n return ` const ${q.fieldPath}_${q.relField.name}Ids = record.${q.parentField} && Array.isArray(record.${q.parentField})\n ? record.${q.parentField}\n .flatMap((parent: Record<string, unknown>) =>\n parent.${q.listFieldName} && Array.isArray(parent.${q.listFieldName})\n ? (parent.${q.listFieldName} as Record<string, unknown>[]).map((item: Record<string, unknown>) => item.${q.relField.name})\n : []\n )\n .filter((id: unknown) => id != null && id !== '')\n .map((id: unknown) => Number.parseInt(String(id), 10))\n .filter((id: number) => !Number.isNaN(id))\n : []`\n }\n return ` // WARNING: Nested list depth ${q.path.length} not yet supported for ${q.path.join('.')}`\n })\n .join('\\n\\n')}\n\n // Phase 2: Execute all queries in parallel\n const [${allRelationshipQueries.map((q) => `${q.fieldPath}_${q.relField.name}Results`).join(', ')}] = await Promise.all([\n${allRelationshipQueries\n .map(\n (q) =>\n ` ${q.fieldPath}_${q.relField.name}Ids.length > 0\n ? db.select({ ${q.relFieldsSelect} }).from(${q.relTable}).where(inArray(${q.relTable}.id, ${q.fieldPath}_${q.relField.name}Ids))\n : Promise.resolve([])`\n )\n .join(',\\n')}\n ])\n\n // Phase 3: Build lookup maps\n${allRelationshipQueries\n .map(\n (q) =>\n ` const ${q.fieldPath}_${q.relField.name}Map = new Map(${q.fieldPath}_${q.relField.name}Results.map((rel) => [rel.id, rel]))`\n )\n .join('\\n')}\n\n // Phase 4: Map relationships back to record\n${allRelationshipQueries\n .map((q) => {\n if (q.path.length === 1) {\n return ` if (record.${q.listFieldName} && Array.isArray(record.${q.listFieldName})) {\n record.${q.listFieldName} = record.${q.listFieldName}.map((item: Record<string, unknown>) => {\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) ? ${q.fieldPath}_${q.relField.name}Map.get(relId) || null : null\n }\n })\n }`\n }\n if (q.path.length === 2) {\n return ` if (record.${q.parentField} && Array.isArray(record.${q.parentField})) {\n record.${q.parentField} = record.${q.parentField}.map((parent: Record<string, unknown>) => {\n if (parent.${q.listFieldName} && Array.isArray(parent.${q.listFieldName})) {\n parent.${q.listFieldName} = (parent.${q.listFieldName} as Record<string, unknown>[]).map((item: Record<string, unknown>) => {\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) ? ${q.fieldPath}_${q.relField.name}Map.get(relId) || null : null\n }\n })\n }\n return parent\n })\n }`\n }\n return ''\n })\n .join('\\n\\n')}\n\n return record\n}\n`\n : ''\n\n // Pre-compute getById function body for M2M-only case (Promise.all optimization)\n const getByIdParallelBody =\n !hasRelationships && hasM2MRelationships\n ? (() => {\n const destructuring = m2mFields.map((f) => `${f.name}Result`).join(', ')\n const queries = m2mFields\n .map((f) => {\n const junctionTableVar = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `db.select({ id: ${junctionTableVar}.${relatedIdField} }).from(${junctionTableVar}).where(eq(${junctionTableVar}.${singularName}Id, id))`\n })\n .join(',\\n ')\n const idMappings = m2mFields\n .map((f) => `const ${f.name}Ids = ${f.name}Result.map(r => r.id)`)\n .join('\\n ')\n const fieldAssignments = m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')\n\n return `\n // Fetch entity and M2M relationships in parallel\n const [result, ${destructuring}] = await Promise.all([\n ${selectClause}.where(eq(${tableVariableName}.id, id)).limit(1),\n ${queries}\n ])\n\n if (result.length === 0) {\n return null\n }\n\n ${idMappings}\n\n return {\n ...result[0],\n${fieldAssignments}\n } as ${pascalSingular}Data`\n })()\n : null\n\n // Generate CRUD functions\n const getFunctions = `export async function get${pascalPlural}(filters?: Get${pascalPlural}Filters): Promise<${pascalPlural}Response> {\n try {\n ${searchQueryBuilder}${resultMapping}\n } catch (error) {\n console.error('Error fetching ${pluralName}:', error)\n return {\n ${toCamelCase(pluralName)}: [],\n total: 0\n }\n }\n}\n${getDistinctFunctions}\n\nexport async function get${pascalSingular}ById(id: number): Promise<${pascalSingular}Data | null> {\n try {${\n getByIdParallelBody !== null\n ? getByIdParallelBody\n : `\n const result = await ${selectClause}.where(eq(${tableVariableName}.id, id)).limit(1)\n\n if (result.length === 0) {\n return null\n }\n ${\n hasRelationships\n ? `\n const row = result[0]\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n `\n : ''\n }\n ${\n listFieldsWithRelationships.length > 0\n ? `const record = {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }\n\n return populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data)`\n : `return {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }`\n }`\n : `\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n \n return {\n ...result[0],\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}\n } as ${pascalSingular}Data`\n : listFieldsWithRelationships.length > 0\n ? `return populate${pascalSingular}ListRelationships(result[0] as ${pascalSingular}Data)`\n : `return result[0] as ${pascalSingular}Data`\n }`\n }`\n }\n } catch (error) {\n console.error('Error fetching ${singularName}:', error)\n return null\n }\n}${\n hasSlugField\n ? `\n\nexport async function get${pascalSingular}BySlug(slug: string): Promise<${pascalSingular}Data | null> {\n try {\n const result = await ${selectClause}.where(eq(${tableVariableName}.slug, slug)).limit(1)\n \n if (result.length === 0) {\n return null\n }\n ${\n hasRelationships\n ? `\n const row = result[0]\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, row.id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n `\n : ''\n }\n ${\n listFieldsWithRelationships.length > 0\n ? `const record = {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }\n\n return populate${pascalSingular}ListRelationships(record as ${pascalSingular}Data)`\n : `return {\n${allDbFields\n .map((f) => {\n if (f.type === 'relationship' && !f.multiple) {\n const relFields = getRelatedSchemaFields(f.relationship!)\n const fieldMappings = relFields\n .map((fieldName) => ` ${fieldName}: row.${f.name}.${fieldName},`)\n .join('\\n')\n return ` ${f.name}: row.${f.name}?.id ? {\n${fieldMappings}\n } : null,`\n }\n if (f.type === 'list' && f.fields && f.fields.some((nf) => nf.type === 'boolean')) {\n return ` ${f.name}: ${generateListFieldConverter(f)},`\n }\n return ` ${f.name}: row.${f.name},`\n })\n .join('\\n')}${\n hasM2MRelationships\n ? `\\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}`\n : ''\n}\n }`\n }`\n : `\n ${\n hasM2MRelationships\n ? `\n // Fetch M2M relationship IDs\n ${m2mFields\n .map((f) => {\n const junctionTable = `${singularName}${f.relationship}`\n const relatedIdField = `${singularize(f.relationship!)}Id`\n return `const ${f.name}Result = await db.select({ id: ${junctionTable}.${relatedIdField} }).from(${junctionTable}).where(eq(${junctionTable}.${singularName}Id, result[0].id))\n const ${f.name}Ids = ${f.name}Result.map(r => r.id)`\n })\n .join('\\n ')}\n \n return {\n ...result[0],\n${m2mFields.map((f) => ` ${f.name}: ${f.name}Ids,`).join('\\n')}\n } as ${pascalSingular}Data`\n : listFieldsWithRelationships.length > 0\n ? `return populate${pascalSingular}ListRelationships(result[0] as ${pascalSingular}Data)`\n : `return result[0] as ${pascalSingular}Data`\n }`\n }\n } catch (error) {\n console.error('Error fetching ${singularName} by slug:', error)\n return null\n }\n}`\n : ''\n }`\n\n // Generate field mappings for create function with proper null handling\n const createFieldMappings = createFields\n .map((field) => ` ${field.name}: ${generateFieldMapping(field)}`)\n .join(',\\n')\n\n const createFunction = `export async function create${pascalSingular}(input: Create${pascalSingular}Input): Promise<Create${pascalSingular}Result> {\n try {\n console.log('[Create ${pascalSingular}] Input:', input)\n ${\n schema.autoSlugify?.enabled\n ? `\n // Auto-generate slug from ${schema.autoSlugify.sourceField} if not provided\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 console.log('[Auto-slug] Generated slug:', input.${schema.autoSlugify.targetField})\n }\n `\n : ''\n }\n // Calculate next sortOrder for new item (place at end)\n const maxSortOrderResult = await db\n .select({ maxOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .orderBy(desc(${tableVariableName}.sortOrder))\n .limit(1)\n const nextSortOrder = (maxSortOrderResult[0]?.maxOrder ?? 0) + 1\n\n const result = await db.insert(${tableVariableName}).values({\n${createFieldMappings},${\n hasDraftMode\n ? `\n published: input.published ?? false,`\n : ''\n }\n sortOrder: nextSortOrder,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString()\n }).returning()\n \n console.log('[Create ${pascalSingular}] ✅ Success:', result[0])\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n ${\n hasRelationships || listFieldsWithRelationships.length > 0\n ? `\n // Fetch with relationships\n const created${pascalSingular} = await get${pascalSingular}ById(result[0].id!)\n\n return {\n success: true,\n ${toCamelCase(singularName)}: created${pascalSingular} ?? undefined\n }`\n : `\n return {\n success: true,\n ${toCamelCase(singularName)}: result[0] as ${pascalSingular}Data\n }`\n }\n } catch (error) {\n console.error('[Create ${pascalSingular}] ❌ Error:', error)\n \n let errorMessage = 'Failed to create ${singularName}'\n \n if (error instanceof Error) {\n // Parse PostgreSQL/Drizzle errors for user-friendly messages\n const pgError = error as unknown as Record<string, unknown>\n \n // Check for NOT NULL constraint violations\n if (error.message.includes('null value in column')) {\n const match = error.message.match(/null value in column \"(\\\\\\\\w+)\"/)\n if (match) {\n const fieldName = match[1]\n errorMessage = \\`Field \"$\\{fieldName}\" is required and cannot be empty\\`\n }\n }\n // Check for data type errors\n else if (error.message.includes('invalid input syntax')) {\n errorMessage = 'Invalid data format provided'\n }\n // Check for constraint violations (unique, foreign key, etc)\n else if (pgError.code === '23505') {\n errorMessage = 'A record with this value already exists'\n }\n // Check for generic empty required fields\n else if (error.message.includes('Failed query') && error.message.includes('values')) {\n errorMessage = 'Please fill in all required fields'\n }\n else {\n errorMessage = error.message\n }\n \n console.error('[Create ${pascalSingular}] Parsed error:', errorMessage)\n }\n \n // Throw error so useMutation onError is triggered\n throw new Error(errorMessage)\n }\n}`\n\n // Generate field metadata for update function\n const fieldMetadata = createFields\n .map((f) => `{ name: '${f.name}', type: '${f.type}', required: ${f.required ?? false} }`)\n .join(',\\n ')\n\n const updateFunction = `export async function update${pascalSingular}(input: Update${pascalSingular}Input): Promise<Update${pascalSingular}Result> {\n try {\n console.log('[Update ${pascalSingular}] Input:', input)\n \n const { id, ...updateData } = input\n ${\n schema.autoSlugify?.enabled\n ? `\n // Auto-generate slug from ${schema.autoSlugify.sourceField} if:\n // 1. Slug is explicitly cleared (empty string) OR\n // 2. Slug is not provided (undefined) AND name is being updated\n if (updateData.${schema.autoSlugify.sourceField}) {\n if (\n updateData.${schema.autoSlugify.targetField} === '' ||\n updateData.${schema.autoSlugify.targetField} === undefined\n ) {\n updateData.${schema.autoSlugify.targetField} = slugify(updateData.${schema.autoSlugify.sourceField})\n console.log('[Auto-slug] Generated slug:', updateData.${schema.autoSlugify.targetField})\n }\n }\n `\n : ''\n }\n \n // Field metadata for processing\n const fieldMeta = [\n ${fieldMetadata}\n ]\n \n // Process updateData to handle optional fields\n const processedData: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(updateData)) {\n // Handle published field directly (boolean field, no special processing needed)\n if (key === 'published') {\n processedData[key] = value\n continue\n }\n \n const field = fieldMeta.find(f => f.name === key)\n if (!field) {\n processedData[key] = value\n continue\n }\n \n // Use helper logic: lists default to [], optional temporal/string fields convert empty to null\n if (field.type === 'list') {\n processedData[key] = value || []\n } else if (\n !field.required &&\n ['date', 'timestamp', 'time', 'string', 'varchar', 'text', 'select'].includes(field.type)\n ) {\n processedData[key] = value && value !== '' ? value : null\n } else {\n processedData[key] = value\n }\n }\n \n const result = await db.update(${tableVariableName})\n .set({\n ...processedData,\n updatedAt: new Date().toISOString()\n })\n .where(eq(${tableVariableName}.id, id))\n .returning()\n \n if (result.length === 0) {\n console.error('[Update ${pascalSingular}] ❌ Not found')\n throw new Error('${pascalSingular} not found')\n }\n \n console.log('[Update ${pascalSingular}] ✅ Success:', result[0])\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n ${\n hasRelationships || listFieldsWithRelationships.length > 0\n ? `\n // Fetch with relationships\n const updated${pascalSingular} = await get${pascalSingular}ById(id)\n\n return {\n success: true,\n ${toCamelCase(singularName)}: updated${pascalSingular} ?? undefined\n }`\n : `\n return {\n success: true,\n ${toCamelCase(singularName)}: result[0] as ${pascalSingular}Data\n }`\n }\n } catch (error) {\n console.error('[Update ${pascalSingular}] ❌ Error:', error)\n \n let errorMessage = 'Failed to update ${singularName}'\n \n if (error instanceof Error) {\n // Parse PostgreSQL/Drizzle errors for user-friendly messages\n const pgError = error as unknown as Record<string, unknown>\n \n // Check for NOT NULL constraint violations\n if (error.message.includes('null value in column')) {\n const match = error.message.match(/null value in column \"(\\\\\\\\w+)\"/)\n if (match) {\n const fieldName = match[1]\n errorMessage = \\`Field \"\\${fieldName}\" is required and cannot be empty\\`\n }\n }\n // Check for data type errors\n else if (error.message.includes('invalid input syntax')) {\n errorMessage = 'Invalid data format provided'\n }\n // Check for constraint violations\n else if (pgError.code === '23505') {\n errorMessage = 'A record with this value already exists'\n }\n else {\n errorMessage = error.message\n }\n \n console.error('[Update ${pascalSingular}] Parsed error:', errorMessage)\n }\n \n // Throw error so useMutation onError is triggered\n throw new Error(errorMessage)\n }\n}`\n\n const deleteFunction = `export async function delete${pascalSingular}(id: number): Promise<Delete${pascalSingular}Result> {\n try {\n await db.delete(${tableVariableName}).where(eq(${tableVariableName}.id, id))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return {\n success: true\n }\n } catch (error) {\n console.error('Error deleting ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${singularName}'\n }\n }\n}\n\nexport async function deleteBulk${pascalPlural}(ids: number[]): Promise<Delete${pascalSingular}Result> {\n try {\n if (ids.length === 0) {\n return {\n success: false,\n error: 'No items selected for deletion'\n }\n }\n\n await db.delete(${tableVariableName}).where(inArray(${tableVariableName}.id, ids))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return {\n success: true\n }\n } catch (error) {\n console.error('Error deleting ${pluralName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to delete ${pluralName}'\n }\n }\n}\n\nexport interface Update${pascalSingular}SortOrderResult {\n success: boolean\n error?: string\n}\n\nexport async function update${pascalSingular}SortOrder(\n id: number,\n direction: 'up' | 'down'\n): Promise<Update${pascalSingular}SortOrderResult> {\n try {\n // Get current item\n const current = await db\n .select({ id: ${tableVariableName}.id, sortOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .where(eq(${tableVariableName}.id, id))\n .limit(1)\n\n if (current.length === 0) {\n return { success: false, error: '${pascalSingular} not found' }\n }\n\n const currentSortOrder = current[0].sortOrder\n\n // Find adjacent item\n const adjacent = await db\n .select({ id: ${tableVariableName}.id, sortOrder: ${tableVariableName}.sortOrder })\n .from(${tableVariableName})\n .where(\n direction === 'up'\n ? lt(${tableVariableName}.sortOrder, currentSortOrder)\n : gt(${tableVariableName}.sortOrder, currentSortOrder)\n )\n .orderBy(\n direction === 'up'\n ? desc(${tableVariableName}.sortOrder)\n : asc(${tableVariableName}.sortOrder)\n )\n .limit(1)\n\n if (adjacent.length === 0) {\n // Already at the top/bottom\n return { success: true }\n }\n\n const adjacentItem = adjacent[0]\n\n // Swap sortOrder values\n await db\n .update(${tableVariableName})\n .set({ sortOrder: adjacentItem.sortOrder })\n .where(eq(${tableVariableName}.id, id))\n\n await db\n .update(${tableVariableName})\n .set({ sortOrder: currentSortOrder })\n .where(eq(${tableVariableName}.id, adjacentItem.id))\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error updating sort order:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update sort order'\n }\n }\n}\n\nexport interface BulkUpdate${pascalPlural}SortOrderResult {\n success: boolean\n error?: string\n}\n\n/**\n * Bulk update sort order for multiple items at once\n */\nexport async function bulkUpdate${pascalPlural}SortOrder(\n updates: Array<{ id: number; sortOrder: number }>\n): Promise<BulkUpdate${pascalPlural}SortOrderResult> {\n try {\n if (updates.length === 0) {\n return { success: true }\n }\n\n // Update each item's sortOrder\n await Promise.all(\n updates.map((update) =>\n db\n .update(${tableVariableName})\n .set({ sortOrder: update.sortOrder })\n .where(eq(${tableVariableName}.id, update.id))\n )\n )\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error bulk updating sort order:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to bulk update sort order'\n }\n }\n}`\n\n // Generate M2M helper functions\n const m2mHelperFunctions = hasM2MRelationships\n ? m2mFields\n .map((f) => {\n const relationshipName = f.relationship || ''\n const relationshipPascal = toPascalCase(relationshipName)\n const relationshipSingular = singularize(relationshipName)\n const junctionTableName = `${singularName}${relationshipPascal}`\n const junctionTableVar = toCamelCase(junctionTableName)\n const _relTableVar = toCamelCase(relationshipName)\n const entityIdColumn = `${singularName}Id`\n const relIdColumn = `${relationshipSingular}Id`\n\n return `\n/**\n * Get ${relationshipName} for a ${singularName}\n */\nexport async function get${relationshipPascal}For${pascalSingular}(${singularName}Id: number): Promise<number[]> {\n try {\n const results = await db\n .select({ ${relIdColumn}: ${junctionTableVar}.${relIdColumn} })\n .from(${junctionTableVar})\n .where(eq(${junctionTableVar}.${entityIdColumn}, ${singularName}Id))\n \n return results.map(r => r.${relIdColumn})\n } catch (error) {\n console.error('Error fetching ${relationshipName} for ${singularName}:', error)\n return []\n }\n}\n\n/**\n * Set ${relationshipName} for a ${singularName}\n */\nexport async function set${relationshipPascal}For${pascalSingular}(\n ${singularName}Id: number,\n ${relationshipName}Ids: number[]\n): Promise<{ success: boolean; error?: string }> {\n try {\n // Delete existing relationships\n await db.delete(${junctionTableVar}).where(eq(${junctionTableVar}.${entityIdColumn}, ${singularName}Id))\n \n // Insert new relationships\n if (${relationshipName}Ids.length > 0) {\n await db.insert(${junctionTableVar}).values(\n ${relationshipName}Ids.map(${relationshipSingular}Id => ({\n ${entityIdColumn}: ${singularName}Id,\n ${relIdColumn}: ${relationshipSingular}Id\n }))\n )\n }\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n\n return { success: true }\n } catch (error) {\n console.error('Error setting ${relationshipName} for ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to set ${relationshipName}'\n }\n }\n}\n\n/**\n * Add ${relationshipName} to a ${singularName}\n */\nexport async function add${relationshipPascal}To${pascalSingular}(\n ${singularName}Id: number,\n ${relationshipName}Ids: number[]\n): Promise<{ success: boolean; error?: string }> {\n try {\n // Get existing relationships\n const existing = await get${relationshipPascal}For${pascalSingular}(${singularName}Id)\n\n // Filter out already existing IDs\n const newIds = ${relationshipName}Ids.filter(id => !existing.includes(id))\n\n // Insert new relationships\n if (newIds.length > 0) {\n await db.insert(${junctionTableVar}).values(\n newIds.map(${relationshipSingular}Id => ({\n ${entityIdColumn}: ${singularName}Id,\n ${relIdColumn}: ${relationshipSingular}Id\n }))\n )\n\n // Immediately invalidate cache for read-your-own-writes\n updateTag(CACHE_TAG)\n }\n\n return { success: true }\n } catch (error) {\n console.error('Error adding ${relationshipName} to ${singularName}:', error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to add ${relationshipName}'\n }\n }\n}`\n })\n .join('\\n')\n : ''\n\n // Generate slugify helper if auto-slugify is enabled\n const slugifyHelper = schema.autoSlugify?.enabled ? generateSlugifyHelper() : ''\n\n // Determine drizzle imports based on search and filters\n const hasFilterableFields = filterableFields.length > 0\n const needsAnd =\n (hasSearch && hasFilterableFields) || (hasFilterableFields && filterableFields.length > 1)\n const needsIlike = hasSearch\n const needsOr = hasSearch\n const needsSql = hasRelationships\n const hasFilterConfig = schema.filters && schema.filters.length > 0\n\n // Build sorted drizzle imports\n // Always include asc for sortOrder ordering, and lt/gt for updateSortOrder action\n const drizzleImportsArray = ['asc', 'desc', 'eq', 'gt', 'inArray', 'lt']\n if (needsAnd) drizzleImportsArray.push('and')\n if (needsIlike) drizzleImportsArray.push('ilike')\n if (needsOr) drizzleImportsArray.push('or')\n if (needsSql) drizzleImportsArray.push('sql')\n if (hasFilterConfig) {\n drizzleImportsArray.push('isNotNull')\n }\n const sortedDrizzleImports = [...new Set(drizzleImportsArray)].sort()\n\n // Generate relationship table imports (sorted alphabetically)\n const relationshipTableImports = hasRelationships\n ? relationshipFields\n .map((f) => toCamelCase(f.relationship!))\n .sort()\n .join(', ')\n : ''\n\n // Collect relationship tables from nested lists\n const nestedRelationshipTables = listFieldsWithRelationships\n .flatMap(({ field }) => {\n return field\n .fields!.filter((f: SchemaField) => f.type === 'relationship' && f.relationship)\n .map((f: SchemaField) => toCamelCase(f.relationship!))\n })\n .filter((table, index, self) => self.indexOf(table) === index) // unique\n .sort()\n\n // Generate junction table imports for M2M relationships\n const m2mTableImports = hasM2MRelationships\n ? m2mFields\n .map((f) => {\n const junctionTableName = `${singularName}${toPascalCase(f.relationship || '')}`\n return toCamelCase(junctionTableName)\n })\n .sort()\n : []\n\n // Generate related table imports for M2M (e.g., 'categories')\n const m2mRelatedTableImports = hasM2MRelationships\n ? m2mFields.map((f) => toCamelCase(f.relationship || '')).sort()\n : []\n\n // Build sorted database imports\n const databaseImportsArray = ['db', tableVariableName]\n if (relationshipTableImports) {\n databaseImportsArray.push(...relationshipTableImports.split(', '))\n }\n if (nestedRelationshipTables.length > 0) {\n databaseImportsArray.push(...nestedRelationshipTables)\n }\n if (hasM2MRelationships) {\n databaseImportsArray.push(...m2mTableImports, ...m2mRelatedTableImports)\n }\n const sortedDatabaseImports = [...new Set(databaseImportsArray)].sort()\n\n // Relationship type imports are no longer needed since we inline the types\n // This ensures nested relationships (e.g., bootcampLink -> instructor) are typed as strings\n // instead of requiring deeply nested Data types\n const relationshipTypeImports = ''\n\n // Type imports (no CSV/JSON import types needed)\n const typeImportsLine = ''\n\n // GitHub helper functions removed - no longer needed\n const _gitHubHelperFunctions = ''\n // Generate nested slug lookup functions (e.g., getChapterBySlug for tutorials)\n const nestedSlugLookupFunctions = schema.nestedSlugLookups?.length\n ? schema.nestedSlugLookups\n .map((lookup) => {\n const nestedName = toPascalCase(lookup.name)\n const nestedNameLower = toCamelCase(lookup.name)\n const pathParts = lookup.path.split('.')\n const slugField = lookup.slugField || 'slug'\n\n // Generate the type for the nested item based on the path\n // For \"modules.chapters\", this finds the chapter type from the modules list field\n const _generateNestedType = () => {\n // Find the nested structure from the schema fields\n // For modules.chapters:\n // - modules is a list field with chapters as a github-chapters field\n const firstPath = pathParts[0]\n const listField = flattenFields(schema.fields).find(\n (f) => f.name === firstPath && f.type === 'list'\n )\n if (!listField || !listField.fields) return 'unknown'\n\n // Look for the chapters field within the list\n if (pathParts.length > 1) {\n const chaptersField = listField.fields.find((f) => f.name === pathParts[1])\n if (chaptersField?.fields) {\n // Build type from the nested fields\n const fieldTypes = chaptersField.fields\n .map((f) => {\n const typeName =\n f.type === 'string' || f.type === 'text' || f.type === 'markdown'\n ? 'string'\n : f.type === 'number'\n ? 'number'\n : f.type === 'boolean'\n ? 'boolean'\n : 'unknown'\n return `${f.name}?: ${typeName}`\n })\n .join('; ')\n return `{ ${fieldTypes} }`\n }\n }\n return 'unknown'\n }\n\n // Generate the traversal code to find the nested item\n const generateTraversalCode = () => {\n if (pathParts.length === 2) {\n // e.g., \"modules.chapters\" - need to traverse modules array, then chapters array within each module\n const [parentArray, nestedArray] = pathParts\n return `\n // Search through ${parentArray} to find the ${nestedNameLower}\n for (const parent of ${singularName}.${parentArray} || []) {\n const items = parent.${nestedArray} as Array<{ ${slugField}?: string; [key: string]: unknown }> | undefined\n if (items) {\n const found = items.find((item) => item.${slugField} === ${nestedNameLower}Slug)\n if (found) {\n return found as ${nestedName}Data\n }\n }\n }`\n }\n // Single level path (e.g., \"chapters\")\n return `\n const items = ${singularName}.${pathParts[0]} as Array<{ ${slugField}?: string; [key: string]: unknown }> | undefined\n if (items) {\n const found = items.find((item) => item.${slugField} === ${nestedNameLower}Slug)\n if (found) {\n return found as ${nestedName}Data\n }\n }`\n }\n\n return `\n/**\n * ${nestedName} data type (nested within ${pascalSingular})\n */\nexport interface ${nestedName}Data {\n title?: string\n slug?: string\n description?: string\n content?: string\n useImage?: boolean\n image?: string\n}\n\n/**\n * Get a ${nestedNameLower} by slug from within a ${singularName}\n * Traverses the ${lookup.path} path to find the matching ${nestedNameLower}\n */\nexport async function get${nestedName}BySlug(${singularName}Slug: string, ${nestedNameLower}Slug: string): Promise<${nestedName}Data | null> {\n try {\n const ${singularName} = await get${pascalSingular}BySlug(${singularName}Slug)\n\n if (!${singularName}) {\n return null\n }\n${generateTraversalCode()}\n\n return null\n } catch (error) {\n console.error('Error fetching ${nestedNameLower} by slug:', error)\n return null\n }\n}`\n })\n .join('\\n')\n : ''\n\n // Generate cache tag for revalidation\n const cacheTagAll = `${pluralName}:all`\n\n // Combine all parts with correct import order\n const content = `'use server'\n\nimport { ${sortedDatabaseImports.join(', ')} } from '${ir.database}'\n${typeImportsLine}\nimport { ${sortedDrizzleImports.join(', ')} } from 'drizzle-orm'\nimport { updateTag } from 'next/cache'\n${relationshipTypeImports ? `${relationshipTypeImports}\\n` : ''}\n// Cache tag for immediate invalidation - ensures users see their changes instantly\nconst CACHE_TAG = '${cacheTagAll}'\n${dataInterface}\n\n${responseInterface}\n\n${filtersInterface}\n\n${createInterface}\n\n${createResultInterface}\n\n${updateInterface}\n\n${updateResultInterface}\n\n${deleteResultInterface}\n${slugifyHelper}${populateListRelationshipsFunction}\n\n${getFunctions}\n\n${createFunction}\n\n${updateFunction}\n\n${deleteFunction}${m2mHelperFunctions}${nestedSlugLookupFunctions}\n`\n\n fs.writeFileSync(actionsFilePath, content, 'utf-8')\n\n // Update index.ts to export new actions\n const indexPath = path.join(actionsDir, 'index.ts')\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n const exportLine = `export * from './${schema.name}'`\n if (!indexContent.includes(exportLine)) {\n indexContent += `\\n${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n }\n } else {\n fs.writeFileSync(indexPath, `export * from './${schema.name}'\\n`, 'utf-8')\n }\n\n // Update package.json exports to include the new actions entry\n const packageJsonPath = path.join(paths.lib, 'package.json')\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n const exportKey = `./actions/${schema.name}`\n if (packageJson.exports && !packageJson.exports[exportKey]) {\n packageJson.exports[exportKey] = {\n types: `./src/actions/${schema.name}.ts`,\n import: `./src/actions/${schema.name}.ts`\n }\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\\n`, 'utf-8')\n }\n }\n\n return `packages/lib/src/actions/${schema.name}.ts`\n}\n","import type { SchemaField } from '../types'\n\n/**\n * Auto-generated ID field that's injected if not present in schema\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 hasIdField = fields.some((f) => f.primaryKey || f.name === 'id')\n if (hasIdField) {\n return fields\n }\n // Prepend the auto-generated ID field\n return [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 // First ensure we have an ID field\n const fieldsWithId = ensureIdField(fields)\n const flattened: SchemaField[] = []\n\n for (const field of fieldsWithId) {\n if (field.type === 'group' && field.fields) {\n // Recursively flatten nested fields in groups (without adding ID again)\n flattened.push(...flattenFieldsWithoutIdCheck(field.fields))\n } else if (field.type === 'tabs' && field.tabs) {\n // Flatten all fields from all tabs (recursively to handle groups inside tabs)\n for (const tab of field.tabs) {\n if (tab.fields) {\n // Don't ensure ID again for nested fields (they're not top-level)\n flattened.push(...flattenFieldsWithoutIdCheck(tab.fields))\n }\n }\n } else {\n flattened.push(field)\n }\n }\n\n return flattened\n}\n\n/**\n * Internal helper to flatten without adding ID (for nested structures)\n */\nfunction flattenFieldsWithoutIdCheck(fields: SchemaField[]): SchemaField[] {\n const flattened: SchemaField[] = []\n\n for (const field of fields) {\n if (field.type === 'group' && 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","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getPaths,\n pluralize,\n singularize,\n toCamelCase,\n toPascalCase,\n toScreamingSnakeCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\ninterface NestedLookupConfig {\n name: string // e.g., 'chapter'\n pascalName: string // e.g., 'Chapter'\n camelName: string // e.g., 'chapter'\n screamingSnake: string // e.g., 'CHAPTER'\n path: string // e.g., 'modules.chapters'\n slugField: string // e.g., 'slug'\n}\n\ninterface CacheConfig {\n name: string // Schema name (e.g., 'posts')\n singularName: string // e.g., 'post'\n pluralName: string // e.g., 'posts'\n pascalSingular: string // e.g., 'Post'\n pascalPlural: string // e.g., 'Posts'\n screamingSnake: string // e.g., 'POSTS'\n hasSlug: boolean\n hasFilters: boolean\n filters: Array<{ field: string; label: string; type?: string }>\n nestedLookups: NestedLookupConfig[] // Nested slug lookup configs\n}\n\n/**\n * Load all schemas from the schemas directory\n */\nfunction loadAllSchemas(): Schema[] {\n const paths = getPaths()\n const schemasDir = paths.schemas\n\n if (!fs.existsSync(schemasDir)) {\n return []\n }\n\n const schemaFiles = fs\n .readdirSync(schemasDir)\n .filter((f) => f.endsWith('.json') && f !== 'schema.json')\n\n const schemas = schemaFiles.map((file) => {\n const content = fs.readFileSync(path.join(schemasDir, file), 'utf-8')\n return JSON.parse(content) as Schema\n })\n\n // Deduplicate by schema name (last one wins if multiple files share the same name)\n const seen = new Map<string, Schema>()\n for (const schema of schemas) {\n seen.set(schema.name, schema)\n }\n return Array.from(seen.values())\n}\n\n/**\n * Build cache config from a schema\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 // Build nested lookup configs\n const nestedLookups: NestedLookupConfig[] = (schema.nestedSlugLookups || []).map((lookup) => ({\n name: lookup.name,\n pascalName: toPascalCase(lookup.name),\n camelName: toCamelCase(lookup.name),\n screamingSnake: toScreamingSnakeCase(lookup.name),\n path: lookup.path,\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: toScreamingSnakeCase(pluralName),\n hasSlug,\n hasFilters: !!(schema.filters && schema.filters.length > 0),\n filters: schema.filters || [],\n nestedLookups\n }\n}\n\n/**\n * Generate cache/tags.ts - Cache tag constants\n */\nfunction generateTagsContent(configs: CacheConfig[]): string {\n const tagEntries: string[] = []\n\n for (const config of configs) {\n const { screamingSnake, pluralName, singularName, hasSlug, nestedLookups } = config\n\n // Add ALL tag\n tagEntries.push(` ${screamingSnake}_ALL: '${pluralName}:all'`)\n\n // Add BY_SLUG tag if schema has slug field\n if (hasSlug) {\n tagEntries.push(\n ` ${screamingSnake}_BY_SLUG: (slug: string) => \\`${pluralName}:slug:\\${slug}\\``\n )\n }\n\n // Add nested lookup tags\n for (const nested of nestedLookups) {\n tagEntries.push(\n ` ${screamingSnake}_${nested.screamingSnake}_BY_SLUG: (${singularName}Slug: string, ${nested.camelName}Slug: string) => \\`${pluralName}:\\${${singularName}Slug}:${nested.name}:\\${${nested.camelName}Slug}\\``\n )\n }\n }\n\n // Sort alphabetically for consistency\n tagEntries.sort()\n\n return `/**\n * Cache tag constants for Next.js 'use cache' invalidation\n * Tags follow the pattern: entity:scope\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nexport const CACHE_TAGS = {\n${tagEntries.join(',\\n')}\n} as const\n`\n}\n\n/**\n * Generate cache/cached-queries.ts - Cached wrapper functions\n */\nfunction generateCachedQueriesContent(configs: CacheConfig[]): string {\n const imports: string[] = []\n const typeImports: string[] = []\n const functions: string[] = []\n\n for (const config of configs) {\n const { pascalSingular, pascalPlural, screamingSnake, singularName, hasSlug, nestedLookups } =\n config\n\n // Add action imports\n imports.push(`get${pascalPlural}`)\n if (hasSlug) {\n imports.push(`get${pascalSingular}BySlug`)\n }\n\n // Add nested lookup action imports\n for (const nested of nestedLookups) {\n imports.push(`get${nested.pascalName}BySlug`)\n }\n\n // All generated actions have a filters parameter, so always add the type import\n typeImports.push(`Get${pascalPlural}Filters`)\n\n // Generate getCached[Plural] function - always with filters support\n functions.push(`\nexport const getCached${pascalPlural} = async (filters?: Get${pascalPlural}Filters) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${pascalPlural}(filters)\n}`)\n\n // Generate getCached[Singular]BySlug function if has slug\n if (hasSlug) {\n functions.push(`\nexport const getCached${pascalSingular}BySlug = async (slug: string) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_BY_SLUG(slug))\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${pascalSingular}BySlug(slug)\n}`)\n }\n\n // Generate getCached[NestedName]BySlug functions\n for (const nested of nestedLookups) {\n functions.push(`\nexport const getCached${nested.pascalName}BySlug = async (${singularName}Slug: string, ${nested.camelName}Slug: string) => {\n cacheLife('max') // Use longest cache duration - stays fresh until updateTag() called\n cacheTag(CACHE_TAGS.${screamingSnake}_${nested.screamingSnake}_BY_SLUG(${singularName}Slug, ${nested.camelName}Slug))\n cacheTag(CACHE_TAGS.${screamingSnake}_ALL)\n\n return get${nested.pascalName}BySlug(${singularName}Slug, ${nested.camelName}Slug)\n}`)\n }\n }\n\n // Sort imports alphabetically\n imports.sort()\n typeImports.sort()\n\n const typeImportsStr =\n typeImports.length > 0\n ? `\\nimport type {\\n ${typeImports.join(',\\n ')}\\n} from '../actions'`\n : ''\n\n return `'use cache'\n\n/**\n * Cached query functions for Next.js 'use cache'\n * Wrap existing actions with cache tags for automatic invalidation\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nimport { cacheLife, cacheTag } from 'next/cache'${typeImportsStr}\nimport {\n ${imports.join(',\\n ')}\n} from '../actions'\nimport { CACHE_TAGS } from './tags'\n${functions.join('\\n')}\n`\n}\n\n/**\n * Generate cache/revalidate.ts - Revalidation helpers\n */\nfunction generateRevalidateContent(configs: CacheConfig[]): string {\n const functions: string[] = []\n\n for (const config of configs) {\n const { pascalSingular, pascalPlural, screamingSnake, singularName, hasSlug, nestedLookups } =\n config\n\n // Generate revalidate[Plural] function\n functions.push(`\nexport const revalidate${pascalPlural} = async () => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n\n // Generate revalidate[Singular]BySlug function if has slug\n if (hasSlug) {\n functions.push(`\nexport const revalidate${pascalSingular}BySlug = async (slug: string) => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_BY_SLUG(slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n\n // Generate revalidate[NestedName]BySlug functions\n for (const nested of nestedLookups) {\n functions.push(`\nexport const revalidate${nested.pascalName}BySlug = async (${singularName}Slug: string, ${nested.camelName}Slug: string) => {\n revalidateTag(CACHE_TAGS.${screamingSnake}_${nested.screamingSnake}_BY_SLUG(${singularName}Slug, ${nested.camelName}Slug), REVALIDATION_STRATEGY)\n revalidateTag(CACHE_TAGS.${screamingSnake}_ALL, REVALIDATION_STRATEGY)\n}`)\n }\n }\n\n return `'use server'\n\n/**\n * Revalidation helpers for Next.js cache invalidation\n * Call these functions after mutations to invalidate relevant caches\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nimport { revalidateTag } from 'next/cache'\nimport { CACHE_TAGS } from './tags'\n\n// Use 'max' strategy for stale-while-revalidate behavior\nconst REVALIDATION_STRATEGY = 'max' as const\n${functions.join('\\n')}\n`\n}\n\n/**\n * Generate index.ts for the cache module\n */\nfunction generateCacheIndexContent(): string {\n return `/**\n * Cache module exports\n *\n * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY\n * Run \\`pnpm generate:admin <schema>\\` to regenerate\n */\n\nexport * from './tags'\nexport * from './cached-queries'\nexport * from './cached-queries-custom'\nexport * from './revalidate'\n`\n}\n\n/**\n * Generate all cache files based on all schemas\n */\nexport async function generateCache(\n _schema: Schema,\n _options: GeneratorOptions\n): Promise<string[]> {\n const paths = getPaths()\n const cacheDir = path.join(paths.lib, 'src', 'cache')\n ensureDir(cacheDir)\n\n // Load all schemas\n const schemas = loadAllSchemas()\n\n // Build cache configs for all schemas\n const configs = schemas.map(buildCacheConfig)\n\n // Sort configs by name for consistent output\n configs.sort((a, b) => a.name.localeCompare(b.name))\n\n const generatedFiles: string[] = []\n\n // Generate tags.ts\n const tagsContent = generateTagsContent(configs)\n const tagsPath = path.join(cacheDir, 'tags.ts')\n fs.writeFileSync(tagsPath, tagsContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/tags.ts')\n\n // Generate cached-queries.ts\n const cachedQueriesContent = generateCachedQueriesContent(configs)\n const cachedQueriesPath = path.join(cacheDir, 'cached-queries.ts')\n fs.writeFileSync(cachedQueriesPath, cachedQueriesContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/cached-queries.ts')\n\n // Generate revalidate.ts\n const revalidateContent = generateRevalidateContent(configs)\n const revalidatePath = path.join(cacheDir, 'revalidate.ts')\n fs.writeFileSync(revalidatePath, revalidateContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/revalidate.ts')\n\n // Generate index.ts\n const indexContent = generateCacheIndexContent()\n const indexPath = path.join(cacheDir, 'index.ts')\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n generatedFiles.push('packages/lib/src/cache/index.ts')\n\n return generatedFiles\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaColumn, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Determine if a column should be sortable by default based on its type\n * Most column types are sortable, except for image, link, custom, and avatar\n */\nfunction isSortableColumn(column: SchemaColumn): boolean {\n // If explicitly set in schema, use that value\n if (typeof column.sortable === 'boolean') {\n return column.sortable\n }\n\n // Default sortable based on column type\n const nonSortableTypes = ['image', 'avatar', 'link', 'custom']\n return !nonSortableTypes.includes(column.type)\n}\n\n/**\n * Generate title fallback chain based on available fields\n * Checks for title, name, then id in that order\n */\nfunction generateTitleFallback(fields: SchemaField[]): string {\n const fieldNames = new Set(fields.map((f) => f.name))\n const fallbacks: string[] = []\n\n // Always include id as final fallback\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\n return fallbacks.join(' || ')\n}\n\n/**\n * Generate column definition based on type\n */\nfunction generateColumnDef(column: SchemaColumn, availableFields: SchemaField[]): string {\n // Handle sortable header\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 // Generate cell renderer based on column type\n let cellDef = ''\n\n const titleFallback = generateTitleFallback(availableFields)\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\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\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\n case 'email':\n cellDef = `cell: ({ row }) => {\n const email = row.getValue('${column.accessorKey}') as string\n return (\n <div className=\"text-sm font-medium\">{email}</div>\n )\n }`\n break\n\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', {\n style: 'currency',\n currency: 'USD'\n }).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\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\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\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\">—</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 {truncate(value, 50)}\n </a>\n )\n }`\n break\n\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\n/**\n * Generate first column definition with integrated checkbox\n */\nfunction generateColumnDefWithCheckbox(\n column: SchemaColumn,\n availableFields: SchemaField[],\n schemaName: string\n): string {\n // Handle sortable header with checkbox\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 // Generate cell renderer with checkbox based on column type\n let cellDef = ''\n const titleFallback = generateTitleFallback(availableFields)\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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={\\`/admin/${schemaName}/\\${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\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={\\`/admin/${schemaName}/\\${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 {truncate(value, 50)}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">—</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\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={\\`/admin/${schemaName}/\\${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/**\n * Generate columns file\n */\nexport async function generateColumns(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const columnsFilePath = path.join(adminDir, 'columns.tsx')\n\n // Check if file exists\n if (fs.existsSync(columnsFilePath) && !options.force) {\n console.warn(` ⚠️ Columns file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/columns.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n // Check what components we need\n let needsArrowUpDown = false\n let needsTrash = false\n let needsBadge = false\n let needsButton = false\n let needsLink = false\n let needsReactQueryClient = false\n let needsToast = false\n let needsAvatar = false\n let needsAlertDialog = false\n let needsTruncate = false\n const needsCheckbox = true // Always need checkbox for row selection\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') {\n needsBadge = true\n }\n if (column.type === 'image' || column.type === 'avatar') {\n needsAvatar = true\n }\n if (column.type === 'link') {\n needsTruncate = true\n }\n }\n\n // Check actions configuration\n const hasEdit = schema.actions?.edit ?? false\n const hasDelete = schema.actions?.delete ?? false\n\n // Always include actions column\n needsButton = true\n if (hasDelete) {\n needsTrash = true\n needsAlertDialog = true\n needsReactQueryClient = true\n needsToast = true\n }\n\n // Get flattened fields for title fallback generation\n const flattenedFields = flattenFields(schema.fields || [])\n const titleFallback = generateTitleFallback(flattenedFields)\n\n // Build imports\n const lucideIcons: string[] = []\n if (needsArrowUpDown) lucideIcons.push('ArrowUpDown')\n // Always include ChevronUp and ChevronDown for reorder buttons\n lucideIcons.push('ChevronDown', 'ChevronUp')\n // Always include Edit icon for first column hover effect\n lucideIcons.push('Edit')\n if (needsTrash) lucideIcons.push('Trash')\n\n const uiComponents: string[] = []\n if (needsButton) uiComponents.push('Button')\n if (needsBadge) uiComponents.push('Badge')\n if (needsCheckbox) uiComponents.push('Checkbox')\n if (needsAvatar) uiComponents.push('Avatar', 'AvatarImage', 'AvatarFallback')\n if (needsAlertDialog) {\n uiComponents.push(\n 'AlertDialog',\n 'AlertDialogAction',\n 'AlertDialogCancel',\n 'AlertDialogContent',\n 'AlertDialogDescription',\n 'AlertDialogFooter',\n 'AlertDialogHeader',\n 'AlertDialogTitle',\n 'AlertDialogTrigger'\n )\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 // Create placeholder custom cell component\n await createCustomCellComponent(schema, column.component, options)\n }\n }\n\n // All columns from schema\n const allColumns = [...schema.columns]\n\n // Modify first column to include checkbox\n const firstColumn = allColumns[0]\n const restColumns = allColumns.slice(1)\n\n // Generate first column with checkbox - always needs Link for navigation\n needsLink = true\n const firstColumnWithCheckbox = generateColumnDefWithCheckbox(\n firstColumn,\n flattenedFields,\n schema.name\n )\n const restColumnDefs = restColumns\n .map((col) => generateColumnDef(col, flattenedFields))\n .join(',\\n')\n\n // Add actions column\n let editButton = ''\n if (hasEdit) {\n editButton = ` <Button variant=\"outline\" className=\"size-8\" asChild>\n <Link href={\\`/admin/${schema.name}/\\${row.original.id}/edit\\`}>\n <Edit className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Edit ${singularName} {${titleFallback}}</span>\n </Link>\n </Button>`\n }\n\n // Add delete handler if delete action is enabled\n let deleteHandler = ''\n\n if (hasDelete) {\n deleteHandler = `\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${pascalSingular}(id)\n \n if (result.success) {\n toast.success('${pascalSingular} deleted successfully')\n // Refetch the list\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${singularName}')\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 ${singularName} \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete ${singularName}</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 ${singularName}.\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 // Reorder handler for move up/down buttons (client-side only when reorder mode is enabled)\n const reorderHandler = `\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 // Reorder column at the beginning (only shown when reorderMode is enabled)\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 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 // Build lib imports\n const libImports: string[] = []\n if (hasDelete) libImports.push(`delete${pascalSingular}`)\n\n const content = `'use client'\n\nimport type { ColumnDef } from '@tanstack/react-table'\n${needsReactQueryClient ? \"import { useQueryClient } from '@tanstack/react-query'\" : ''}\n${lucideIcons.length > 0 ? `import { ${lucideIcons.join(', ')} } from 'lucide-react'` : ''}\n${needsLink ? \"import Link from 'next/link'\" : ''}\nimport * as React from 'react'\n${needsToast ? \"import { toast } from 'sonner'\" : ''}\n${uiComponents.length > 0 ? `import {\\n ${uiComponents.join(',\\n ')}\\n} from '${ir.adminUi}'` : ''}\n${libImports.length > 0 ? `import { ${libImports.join(', ')} } from '${ir.actions(schema.name)}'` : ''}\nimport type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n${needsTruncate ? `import { truncate } from '${ir.utils}'` : ''}\n${customImports.join('\\n')}\n${deleteHandler}${reorderHandler}\nexport const columns: ColumnDef<${pascalSingular}Data>[] = [\n${reorderColumn},\n${firstColumnWithCheckbox}${restColumnDefs ? `,\\n${restColumnDefs}` : ''},\n${actionsColumn}\n]\n`\n\n fs.writeFileSync(columnsFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/columns.tsx`\n}\n\n/**\n * Create placeholder custom cell component\n */\nasync function createCustomCellComponent(\n schema: Schema,\n componentName: string,\n options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const ir = getImportResolver()\n const cellsDir = path.join(paths.app, 'app/(admin)/admin', schema.name, 'cells')\n ensureDir(cellsDir)\n\n const componentFilePath = path.join(cellsDir, `${componentName}.tsx`)\n\n // Check if file exists\n if (fs.existsSync(componentFilePath) && !options.force) {\n return\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n const content = `import type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n\ninterface ${componentName}Props {\n data: ${pascalSingular}Data\n}\n\nexport function ${componentName}({ data }: ${componentName}Props) {\n // TODO: Implement custom cell rendering\n return (\n <div>\n {/* Add your custom rendering logic here */}\n {JSON.stringify(data)}\n </div>\n )\n}\n`\n\n fs.writeFileSync(componentFilePath, content, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n singularize,\n singularizeLabel,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate create page component\n */\nexport async function generateCreatePage(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string> {\n const paths = getPaths()\n const newDir = path.join(paths.app, 'app/(admin)/admin', schema.name, 'new')\n ensureDir(newDir)\n\n const pageFilePath = path.join(newDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Create page already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/new/page.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n\n const ir = getImportResolver()\n\n const content = `import { ArrowLeft } from 'lucide-react'\nimport Link from 'next/link'\nimport { connection } from 'next/server'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\nimport { Button } from '${ir.adminUi}'\nimport { ${pascalSingular}Form } from '../${schema.name}-form'\n\nexport default async function Page() {\n await connection()\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader\n title=\"Create ${singularizeLabel(schema.label)}\"\n description=\"Add a new ${singularizeLabel(schema.label).toLowerCase()} to the system\"\n />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/${schema.name}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${schema.label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-6\">\n <${pascalSingular}Form key={Date.now()} />\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/new/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getMigrationTimestamp,\n getPaths,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Extract many-to-many relationship fields from schema\n */\nfunction getManyToManyFields(fields: SchemaField[]): SchemaField[] {\n return flattenFields(fields).filter(\n (f) => f.type === 'relationship' && f.multiple === true && f.relationship\n )\n}\n\n/**\n * Check if field name suggests it's a URL field\n */\nfunction isUrlField(fieldName: string): boolean {\n const urlKeywords = [\n 'url',\n 'website',\n 'link',\n 'href',\n 'src',\n 'image',\n 'banner',\n 'logo',\n 'video',\n 'media'\n ]\n const lowerName = fieldName.toLowerCase()\n return urlKeywords.some((keyword) => lowerName.includes(keyword))\n}\n\n/**\n * Map field type to Drizzle type and track required import\n */\nfunction getDrizzleType(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 // Use text() for URL-like fields or if no length specified and field name suggests URL\n if (isUrlField(field.name) && !field.length) {\n requiredImports.add('text')\n return 'text()'\n }\n requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'image':\n // Image fields (URLs) should use text() to handle long URLs\n requiredImports.add('text')\n return 'text()'\n case 'text':\n case 'markdown':\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: 10, scale: 2 })'\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 requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'select':\n requiredImports.add('varchar')\n return field.length ? `varchar({ length: ${field.length} })` : 'varchar({ length: 255 })'\n case 'list':\n requiredImports.add('jsonb')\n // If list has nested fields, store as array of objects, otherwise as array of strings\n if (field.fields && field.fields.length > 0) {\n // Generate type for nested object, handling nested lists and groups recursively\n const nestedType = field.fields\n .flatMap((f) => {\n let type: string\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n // Nested list with fields - array of objects\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 === 'group' && f.fields && f.fields.length > 0) {\n // Nested group - object with sub-fields\n const innerType = f.fields\n .map((gf) => {\n let gfType: string\n if (gf.type === 'boolean') {\n gfType = 'boolean'\n } else if (gf.type === 'number' || gf.type === 'decimal') {\n gfType = 'number'\n } else {\n gfType = 'string'\n }\n return `${quotePropertyName(gf.name)}?: ${gfType}`\n })\n .join('; ')\n type = `{ ${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 fields = [`${quotePropertyName(f.name)}?: ${type}`]\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n fields.push(`${quotePropertyName(`${f.name}Icon`)}?: string`)\n }\n return fields\n })\n .join('; ')\n return `jsonb().$type<Array<{ ${nestedType} }>>()`\n }\n return 'jsonb().$type<string[]>()'\n case 'curriculum':\n requiredImports.add('jsonb')\n return `jsonb().$type<{ 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 requiredImports.add('text')\n return 'text()'\n }\n}\n\n/**\n * Get field modifiers (notNull, default, primaryKey)\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 // Skip empty string defaults for date/timestamp fields as they're invalid in PostgreSQL\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 if (typeof field.default === 'boolean') {\n modifiers.push(`.default(${field.default})`)\n } else {\n modifiers.push(`.default(${field.default})`)\n }\n }\n\n // Add default timestamps for createdAt and updatedAt\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 * Generate Drizzle schema definition\n */\nfunction generateSchemaDefinition(\n schema: Schema,\n requiredImports: Set<string>,\n needsSql: { value: boolean }\n): string {\n const tableName = toPascalCase(schema.name)\n\n // Always need pgTable\n requiredImports.add('pgTable')\n\n // Flatten fields to handle groups, excluding many-to-many relationships (handled via junction tables)\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n // Add published field automatically when draft mode is enabled\n const hasDraftMode = schema.actions?.draft === true\n const hasPublishedField = dbFields.some((f) => f.name === 'published')\n\n const fieldDefinitions = dbFields\n .map((field) => {\n const drizzleType = getDrizzleType(field, requiredImports)\n const modifiers = getFieldModifiers(field, needsSql)\n return ` ${field.name}: ${drizzleType}${modifiers}`\n })\n .join(',\\n')\n\n // Add published field for draft mode if not already present\n const publishedField =\n hasDraftMode && !hasPublishedField ? `,\\n published: boolean().notNull().default(false)` : ''\n\n if (hasDraftMode && !hasPublishedField) {\n requiredImports.add('boolean')\n }\n\n // Automatically add createdAt and updatedAt if not present\n const hasCreatedAt = dbFields.some((f) => f.name === 'createdAt')\n const hasUpdatedAt = dbFields.some((f) => f.name === 'updatedAt')\n\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 // Add sortOrder field for row reordering (automatically added to all tables)\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n let sortOrderField = ''\n if (!hasSortOrder) {\n requiredImports.add('integer')\n sortOrderField = `,\\n sortOrder: integer().notNull().default(0)`\n }\n\n // Convert kebab-case schema names to camelCase for variable names\n const variableName = toCamelCase(schema.name)\n\n return `\nexport const ${variableName} = pgTable(\n '${tableName}',\n {\n${fieldDefinitions}${publishedField}${timestampFields}${sortOrderField}\n }\n)\n`\n}\n\n/**\n * Generate junction table definition for many-to-many relationships\n */\nfunction generateJunctionTableDefinition(\n schemaName: string,\n relationshipField: SchemaField,\n requiredImports: Set<string>\n): string {\n const singularSchema = singularize(schemaName)\n const singularRelationship = singularize(relationshipField.relationship || '')\n\n // Junction table name: e.g., postCategories\n const junctionTableName = `${singularSchema}${toPascalCase(relationshipField.relationship || '')}`\n const junctionTablePascal = toPascalCase(junctionTableName)\n\n // Column names: postId, categoryId\n const schemaIdColumn = `${singularSchema}Id`\n const relationshipIdColumn = `${singularRelationship}Id`\n\n // Table references\n const schemaTableRef = toCamelCase(schemaName)\n const relationshipTableRef = toCamelCase(relationshipField.relationship || '')\n\n requiredImports.add('pgTable')\n requiredImports.add('integer')\n requiredImports.add('primaryKey')\n\n return `\nexport const ${toCamelCase(junctionTableName)} = pgTable(\n '${junctionTablePascal}',\n {\n ${schemaIdColumn}: integer().notNull().references(() => ${schemaTableRef}.id, { onDelete: 'cascade' }),\n ${relationshipIdColumn}: integer().notNull().references(() => ${relationshipTableRef}.id, { onDelete: 'cascade' })\n },\n (table) => [primaryKey({ columns: [table.${schemaIdColumn}, table.${relationshipIdColumn}] })]\n)\n`\n}\n\n/**\n * Generate SQL for junction table migration\n */\nfunction generateJunctionTableSQL(schemaName: string, relationshipField: SchemaField): string {\n const singularSchema = singularize(schemaName)\n const singularRelationship = singularize(relationshipField.relationship || '')\n\n // Junction table name: e.g., PostCategories\n const junctionTableName = `${singularSchema}${toPascalCase(relationshipField.relationship || '')}`\n const junctionTablePascal = toPascalCase(junctionTableName)\n\n // Column names\n const schemaIdColumn = `${singularSchema}Id`\n const relationshipIdColumn = `${singularRelationship}Id`\n\n // Referenced tables\n const schemaTable = toPascalCase(schemaName)\n const relationshipTable = toPascalCase(relationshipField.relationship || '')\n\n return `-- CreateJunctionTable\nCREATE TABLE \"${junctionTablePascal}\" (\n \"${schemaIdColumn}\" INTEGER NOT NULL REFERENCES \"${schemaTable}\"(\"id\") ON DELETE CASCADE,\n \"${relationshipIdColumn}\" INTEGER NOT NULL REFERENCES \"${relationshipTable}\"(\"id\") ON DELETE CASCADE,\n PRIMARY KEY (\"${schemaIdColumn}\", \"${relationshipIdColumn}\")\n);\n\n-- CreateIndex for faster lookups\nCREATE INDEX \"idx_${junctionTablePascal}_${schemaIdColumn}\" ON \"${junctionTablePascal}\" (\"${schemaIdColumn}\");\nCREATE INDEX \"idx_${junctionTablePascal}_${relationshipIdColumn}\" ON \"${junctionTablePascal}\" (\"${relationshipIdColumn}\");\n`\n}\n\n/**\n * Map field type to SQL type\n */\nfunction getSQLType(field: SchemaField): string {\n switch (field.type) {\n case 'serial':\n return 'SERIAL PRIMARY KEY'\n case 'string':\n case 'varchar':\n // Use TEXT for URL-like fields or if no length specified and field name suggests URL\n if (isUrlField(field.name) && !field.length) {\n return 'TEXT'\n }\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n case 'image':\n // Image fields (URLs) should use TEXT to handle long URLs\n return 'TEXT'\n case 'text':\n case 'markdown':\n return 'TEXT'\n case 'number':\n case 'decimal':\n if (field.precision && field.scale) {\n return `DECIMAL(${field.precision}, ${field.scale})`\n }\n return 'INTEGER'\n case 'boolean':\n return 'BOOLEAN'\n case 'timestamp':\n return 'TIMESTAMP(3)'\n case 'date':\n return 'DATE'\n case 'time':\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n case 'select':\n return field.length ? `VARCHAR(${field.length})` : 'VARCHAR(255)'\n default:\n return 'TEXT'\n }\n}\n\n/**\n * Generate SQL migration file\n */\nfunction generateMigrationSQL(schema: Schema): string {\n const tableName = toPascalCase(schema.name)\n\n // Flatten fields to handle groups, excluding many-to-many relationships\n const dbFields = flattenFields(schema.fields).filter(\n (f) => !(f.type === 'relationship' && f.multiple === true)\n )\n\n const columns = dbFields\n .filter((field) => !field.primaryKey) // Serial primary keys are handled separately\n .map((field) => {\n let def = ` \"${field.name}\" ${getSQLType(field)}`\n\n if (field.required) {\n def += ' NOT NULL'\n }\n\n // Skip empty string defaults for date/timestamp fields as they're invalid in PostgreSQL\n const isDateField = field.type === 'date' || field.type === 'timestamp'\n const hasValidDefault = field.default !== undefined && !(isDateField && field.default === '')\n\n if (hasValidDefault) {\n if (typeof field.default === 'string') {\n def += ` DEFAULT '${field.default}'`\n } else if (typeof field.default === 'boolean') {\n def += ` DEFAULT ${field.default}`\n } else {\n def += ` DEFAULT ${field.default}`\n }\n }\n\n // Add default timestamps\n if (field.name === 'createdAt' || field.name === 'updatedAt') {\n def += ' DEFAULT CURRENT_TIMESTAMP'\n }\n\n return def\n })\n\n // Add primary key field at the beginning\n const pkField = dbFields.find((f) => f.primaryKey)\n const pkColumn = pkField\n ? ` \"${pkField.name}\" ${getSQLType(pkField)}`\n : ' \"id\" SERIAL PRIMARY KEY'\n\n // Add sortOrder column for row reordering\n const hasSortOrder = dbFields.some((f) => f.name === 'sortOrder')\n const sortOrderColumn = !hasSortOrder ? ',\\n \"sortOrder\" INTEGER NOT NULL DEFAULT 0' : ''\n\n const allColumns = [pkColumn, ...columns].join(',\\n') + sortOrderColumn\n\n // Add index on sortOrder for efficient ordering queries\n const sortOrderIndex = !hasSortOrder\n ? `\\n\\n-- CreateIndex for sortOrder\\nCREATE INDEX \"idx_${tableName}_sortOrder\" ON \"${tableName}\" (\"sortOrder\");`\n : ''\n\n return `-- CreateTable\nCREATE TABLE \"${tableName}\" (\n${allColumns}\n);${sortOrderIndex}\n`\n}\n\n/**\n * Update imports in schema.ts file\n */\nfunction updateImports(content: string, requiredImports: Set<string>, needsSql: boolean): string {\n // Parse existing imports\n const drizzleImportMatch = content.match(\n /import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/\n )\n const sqlImportExists = content.includes(\"import { sql } from 'drizzle-orm'\")\n\n let existingImports = new Set<string>()\n if (drizzleImportMatch) {\n const imports = drizzleImportMatch[1]\n .split(',')\n .map((i) => i.trim())\n .filter((i) => i)\n existingImports = new Set(imports)\n }\n\n // Merge required imports with existing\n const allImports = new Set([...existingImports, ...requiredImports])\n const sortedImports = Array.from(allImports).sort()\n\n // Build new import statement\n const newDrizzleImport = `import {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'`\n\n // Update content\n let updatedContent = content\n\n // Replace or add drizzle-orm/pg-core import\n if (drizzleImportMatch) {\n updatedContent = updatedContent.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm\\/pg-core['\"]/,\n newDrizzleImport\n )\n } else {\n // Add import after sql import or at the beginning\n if (sqlImportExists) {\n updatedContent = updatedContent.replace(\n /import\\s+\\{[^}]+\\}\\s+from\\s+['\"]drizzle-orm['\"]/,\n (match) => `${match}\\n${newDrizzleImport}`\n )\n } else {\n updatedContent = `${newDrizzleImport}\\n${updatedContent}`\n }\n }\n\n // Add sql import if needed and not present\n if (needsSql && !sqlImportExists) {\n updatedContent = `import { sql } from 'drizzle-orm'\\n${updatedContent}`\n }\n\n return updatedContent\n}\n\n/**\n * Helper function to find table end position in schema file\n */\nfunction findTableEnd(content: string, startIndex: number): number {\n let depth = 0\n let inString = false\n let stringChar = ''\n let tableEnd = startIndex\n\n for (let i = startIndex; i < content.length; i++) {\n const char = content[i]\n const prevChar = i > 0 ? content[i - 1] : ''\n\n // Handle string literals\n if ((char === '\"' || char === \"'\" || char === '`') && prevChar !== '\\\\') {\n if (!inString) {\n inString = true\n stringChar = char\n } else if (char === stringChar) {\n inString = false\n }\n continue\n }\n\n if (inString) continue\n\n if (char === '(' || char === '{' || char === '[') depth++\n if (char === ')' || char === '}' || char === ']') depth--\n\n // Found the closing paren of pgTable()\n if (depth === 0 && char === ')') {\n tableEnd = i + 1\n break\n }\n }\n\n return tableEnd\n}\n\n/**\n * Update packages/database/src/schema.ts with new table\n */\nasync function updateSchemaFile(schema: Schema, options: GeneratorOptions): Promise<void> {\n const paths = getPaths()\n const schemaFilePath = path.join(paths.database, 'src/schema.ts')\n\n let currentContent = ''\n if (fs.existsSync(schemaFilePath)) {\n currentContent = fs.readFileSync(schemaFilePath, 'utf-8')\n }\n\n // Convert kebab-case schema names to camelCase for variable names\n const variableName = toCamelCase(schema.name)\n\n // Check if table already exists\n if (currentContent.includes(`export const ${variableName} =`) && !options.force) {\n console.warn(\n ` ⚠️ Table \"${variableName}\" already exists in schema.ts. Use --force to overwrite.`\n )\n return\n }\n\n // Track required imports\n const requiredImports = new Set<string>()\n const needsSql = { value: false }\n\n // Generate new table definition\n const newTableDef = generateSchemaDefinition(schema, requiredImports, needsSql)\n\n // Generate junction table definitions for many-to-many relationships\n const m2mFields = getManyToManyFields(schema.fields)\n const _junctionTableDefs = m2mFields\n .map((field) => generateJunctionTableDefinition(schema.name, field, requiredImports))\n .join('')\n\n // Update imports\n let updatedContent = currentContent\n if (updatedContent) {\n updatedContent = updateImports(updatedContent, requiredImports, needsSql.value)\n } else {\n // New file - create from scratch\n const sortedImports = Array.from(requiredImports).sort()\n const importsStr = needsSql.value\n ? `import { sql } from 'drizzle-orm'\\nimport {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'\\n`\n : `import {\\n ${sortedImports.join(',\\n ')}\\n} from 'drizzle-orm/pg-core'\\n`\n updatedContent = importsStr\n }\n\n // Add the new table definition\n if (options.force && currentContent.includes(`export const ${variableName} =`)) {\n // Replace existing definition\n const tableStart = currentContent.indexOf(`export const ${variableName} =`)\n if (tableStart !== -1) {\n const tableEnd = findTableEnd(currentContent, tableStart)\n updatedContent =\n currentContent.slice(0, tableStart) + newTableDef.trim() + currentContent.slice(tableEnd)\n }\n } else {\n // Append new definition\n updatedContent = `${updatedContent.trimEnd()}\\n${newTableDef}`\n }\n\n // Handle junction tables for many-to-many relationships\n for (const m2mField of m2mFields) {\n const singularSchema = singularize(schema.name)\n const junctionTableName = `${singularSchema}${toPascalCase(m2mField.relationship || '')}`\n const junctionVarName = toCamelCase(junctionTableName)\n\n if (options.force && updatedContent.includes(`export const ${junctionVarName} =`)) {\n // Replace existing junction table\n const junctionStart = updatedContent.indexOf(`export const ${junctionVarName} =`)\n if (junctionStart !== -1) {\n const junctionEnd = findTableEnd(updatedContent, junctionStart)\n const junctionDef = generateJunctionTableDefinition(schema.name, m2mField, requiredImports)\n updatedContent =\n updatedContent.slice(0, junctionStart) +\n junctionDef.trim() +\n updatedContent.slice(junctionEnd)\n }\n } else if (!updatedContent.includes(`export const ${junctionVarName} =`)) {\n // Append junction table\n const junctionDef = generateJunctionTableDefinition(schema.name, m2mField, requiredImports)\n updatedContent = `${updatedContent.trimEnd()}\\n${junctionDef}`\n }\n }\n\n // Re-update imports to include any new ones from junction tables\n updatedContent = updateImports(updatedContent, requiredImports, needsSql.value)\n\n ensureDir(path.dirname(schemaFilePath))\n fs.writeFileSync(schemaFilePath, updatedContent, 'utf-8')\n}\n\n/**\n * Remove previous migrations for a schema\n */\nfunction removePreviousMigrations(schemaName: string, migrationDir: string): void {\n try {\n const files = fs.readdirSync(migrationDir)\n const migrationPattern = new RegExp(`^\\\\d+_${schemaName}\\\\.sql$`)\n\n for (const file of files) {\n if (migrationPattern.test(file)) {\n const filePath = path.join(migrationDir, file)\n fs.unlinkSync(filePath)\n console.log(` 🗑️ Removed previous migration: ${file}`)\n }\n }\n } catch (error) {\n // If directory doesn't exist or read fails, that's okay - no migrations to remove\n if (error instanceof Error && !error.message.includes('ENOENT')) {\n console.warn(` ⚠️ Warning: Could not remove previous migrations: ${error.message}`)\n }\n }\n}\n\n/**\n * Generate database schema and migration files\n */\nexport async function generateDatabase(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string[]> {\n const paths = getPaths()\n const files: string[] = []\n\n // Update schema.ts in packages/database\n await updateSchemaFile(schema, options)\n files.push('packages/database/src/schema.ts')\n\n // Generate migration SQL in packages/database/drizzle\n const migrationDir = path.join(paths.database, 'drizzle')\n ensureDir(migrationDir)\n\n // Remove previous migrations for this schema if --force is used\n if (options.force) {\n removePreviousMigrations(schema.name, migrationDir)\n }\n\n const timestamp = getMigrationTimestamp()\n const migrationFileName = `${timestamp}_${schema.name}.sql`\n const migrationFilePath = path.join(migrationDir, migrationFileName)\n\n // Generate main table SQL\n let migrationSQL = generateMigrationSQL(schema)\n\n // Generate junction table SQL for many-to-many relationships\n const m2mFields = getManyToManyFields(schema.fields)\n for (const field of m2mFields) {\n migrationSQL += `\\n${generateJunctionTableSQL(schema.name, field)}`\n }\n\n fs.writeFileSync(migrationFilePath, migrationSQL, 'utf-8')\n files.push(`packages/database/drizzle/${migrationFileName}`)\n\n return files\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate edit page component\n */\nexport async function generateEditPage(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const editDir = path.join(paths.app, 'app/(admin)/admin', schema.name, '[id]', 'edit')\n ensureDir(editDir)\n\n const pageFilePath = path.join(editDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Edit page already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/[id]/edit/page.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const camelSingular = toCamelCase(singularName)\n\n const ir = getImportResolver()\n\n const content = `import { notFound } from 'next/navigation'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\nimport { get${pascalSingular}ById } from '${ir.actions(schema.name)}'\nimport { ${pascalSingular}Form } from '../../${schema.name}-form'\nimport { Button } from '${ir.adminUi}'\nimport Link from 'next/link'\nimport { ArrowLeft } from 'lucide-react'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n const ${camelSingular} = await get${pascalSingular}ById(Number.parseInt(id, 10))\n\n if (!${camelSingular}) {\n notFound()\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader\n title=\"Edit ${pascalSingular}\"\n description=\"Update ${singularName} information\"\n />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/${schema.name}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${schema.label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-6\">\n <${pascalSingular}Form key={${camelSingular}.id} initialData={${camelSingular}} />\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/[id]/edit/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types'\nimport { ensureDir, getPaths, toPascalCase } from '../utils'\n\n/**\n * Check if a form schema has dynamicFields\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[]): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'group' && field.fields) {\n // Recursively flatten group fields - don't include the group itself\n return flattenFields(field.fields)\n }\n // Only return non-group fields (no need to propagate conditions for email)\n // Skip dynamicFields - they're handled separately via customFields\n return field.type === 'group' || field.type === 'dynamicFields' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Get TypeScript type for a form field\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) {\n return 'Record<string, unknown>[] | null'\n }\n return 'string[] | null'\n default:\n return 'string | null'\n }\n}\n\n/**\n * Generate value display for a field in email\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\n case 'upload':\n case 'file':\n return `{${name} ? (\n <Link href={${name}} style={link}>Download File</Link>\n ) : (\n 'No file uploaded'\n )}`\n\n case 'email':\n return `{${name} ? (\n <Link href={\\`mailto:\\${${name}}\\`} style={link}>{${name}}</Link>\n ) : (\n 'N/A'\n )}`\n\n case 'url':\n return `{${name} ? (\n <Link href={${name}} style={link}>{${name}}</Link>\n ) : (\n 'N/A'\n )}`\n\n case 'list':\n case 'multiselect':\n if (field.fields && field.fields.length > 0) {\n // Object list\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 'N/A'\n )}`\n }\n // Simple array\n return `{${name} && Array.isArray(${name}) && ${name}.length > 0 ? ${name}.join(', ') : 'N/A'}`\n\n case 'date':\n return `{${name} ? new Date(${name}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : 'N/A'}`\n\n default:\n return `{${name} ?? 'N/A'}`\n }\n}\n\n/**\n * Generate email template for form submission notifications\n */\nexport async function generateEmailTemplate(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string | null> {\n if (!schema.notificationEmail) {\n return null\n }\n\n const paths = getPaths()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const fields = getAllFields(schema).filter((f) => f.name) // Get flattened fields with names only\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Check if we need Link component\n const needsLink = fields.some(\n (f) => f.type === 'upload' || f.type === 'file' || f.type === 'email' || f.type === 'url'\n )\n\n // Check if we need listItem style (for object lists)\n const needsListItem = fields.some(\n (f) => (f.type === 'list' || f.type === 'multiselect') && f.fields && f.fields.length > 0\n )\n\n // Generate interface for email props\n const emailPropsInterfaceFields = fields\n .map((f) => ` ${f.name}: ${getTypeForField(f)}`)\n .join('\\n')\n const customFieldsLine = includeDynamicFields\n ? '\\n customFields?: Record<string, unknown> | null'\n : ''\n const emailPropsInterface = emailPropsInterfaceFields + customFieldsLine\n\n // Generate field sections for 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 // Generate custom fields section for email\n const customFieldsSection = includeDynamicFields\n ? `\n\n {/* Custom Fields (from CMS) */}\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 const propsDestructured = includeDynamicFields\n ? `${fields.map((f) => f.name).join(',\\n ')},\n customFields,\n submittedAt`\n : `${fields.map((f) => f.name).join(',\\n ')},\n submittedAt`\n\n const emailContent = `import { Body, Container, Head, Heading, Html${needsLink ? ', Link' : ''}, Preview, Row, Section, Text } from '@react-email/components'\n\ninterface ${pascalName}SubmissionEmailProps {\n${emailPropsInterface}\n submittedAt: string\n}\n\nexport function ${pascalName}SubmissionEmail({\n ${propsDestructured}\n}: ${pascalName}SubmissionEmailProps) {\n return (\n <Html>\n <Head />\n <Preview>New ${schema.label} Submission</Preview>\n <Body style={main}>\n <Container style={container}>\n {/* Header with Logo */}\n <Section style={header}>\n <Text style={logoText}>BetterStart</Text>\n </Section>\n\n {/* Title */}\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 {/* Form Fields */}\n <Section style={card}>\n${fieldSections}${customFieldsSection}\n </Section>\n\n {/* Footer */}\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\n// Brand Colors\nconst colors = {\n primary: '#7c3aed',\n primaryDark: '#6d28d9',\n background: '#f8fafc',\n cardBg: '#ffffff',\n text: '#1e293b',\n textMuted: '#64748b',\n textLight: '#94a3b8',\n border: '#e2e8f0',\n borderLight: '#f1f5f9',\n}\n\n// Styles\nconst main = {\n backgroundColor: colors.background,\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Ubuntu, 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',\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',\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',\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\n${\n needsLink\n ? `const link = {\n color: colors.primary,\n fontWeight: '500',\n textDecoration: 'none',\n}\n\n`\n : ''\n}${\n needsListItem\n ? `const 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}${\n includeDynamicFields\n ? `const 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',\n margin: '0 0 8px',\n}\n\n`\n : ''\n}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',\n margin: '0',\n}\n`\n\n const emailPath = path.join(paths.app, 'emails', `${formName}-submission.tsx`)\n ensureDir(path.dirname(emailPath))\n\n if (fs.existsSync(emailPath) && !options.force) {\n console.warn(`⚠️ Email template already exists: ${emailPath}. Use --force to overwrite.`)\n return emailPath\n }\n\n fs.writeFileSync(emailPath, emailContent, 'utf-8')\n console.log(` ✓ Email template generated: ${emailPath}`)\n\n return emailPath\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema, SchemaField } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n quotePropertyName,\n singularize,\n toCamelCase,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Get form field type\n */\nfunction 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\n/**\n * Get Zod schema type\n */\nfunction 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 // Use z.number() directly - form inputs with type=\"number\" provide numbers\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 // Transform empty strings to undefined for optional date fields\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 if (!field.required) {\n // Transform empty strings to undefined for optional image fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const imageBase = `z.string().min(1, 'Please upload an image for ${label}').url('Please provide a valid image URL')`\n return field.length ? `${imageBase}.max(${field.length})` : imageBase\n }\n case 'video': {\n if (!field.required) {\n // Transform empty strings to undefined for optional video fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const videoBase = `z.string().min(1, 'Please upload a video for ${label}').url('Please provide a valid video URL')`\n return field.length ? `${videoBase}.max(${field.length})` : videoBase\n }\n case 'media': {\n if (!field.required) {\n // Transform empty strings to undefined for optional media fields\n return 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n }\n const mediaBase = `z.string().min(1, 'Please upload media for ${label}').url('Please provide a valid media URL')`\n return field.length ? `${mediaBase}.max(${field.length})` : mediaBase\n }\n case 'list':\n // Handle list with nested fields (array of objects)\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .flatMap((nestedField) => {\n const defs: string[] = []\n const nestedZodType = getZodType(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 // Add icon field if hasIcon is true\n if (nestedField.hasIcon) {\n defs.push(\n ` ${quotePropertyName(`${nestedField.name}Icon`)}: z.string().optional()`\n )\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 // Handle list with items (simple string array)\n if (field.items?.type === 'string' || field.items?.type === 'varchar') {\n const itemSchema = field.items.length\n ? `z.string().max(${field.items.length})`\n : '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 case 'select': {\n // Select fields are stored as strings, validate against options if provided\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 const base = field.required\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().optional()'\n return base\n }\n case 'icon': {\n // Icon fields are stored as strings (icon names)\n const base = field.required\n ? `z.string().min(1, '${label} is required')`\n : 'z.string().optional()'\n return field.length ? `${base}.max(${field.length})` : base\n }\n case 'relationship': {\n // Many-to-many relationships store array of IDs\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 // Single relationship fields store the ID of the related entity as a string\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n case 'curriculum': {\n // Curriculum stores both items and weeks - mode determines which editor to show\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 }\n case 'group': {\n // Group fields are nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((nestedField) => {\n const nestedZodType = getZodType(nestedField)\n const alreadyOptional = nestedZodType.includes('.optional()')\n let nestedDef = ` ${quotePropertyName(nestedField.name)}: ${nestedZodType}`\n if (!nestedField.required && !alreadyOptional) {\n nestedDef += '.optional()'\n }\n return nestedDef\n })\n .join(',\\n')\n return field.required\n ? `z.object({\\n${nestedFields}\\n })`\n : `z.object({\\n${nestedFields}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n }\n default:\n return field.required ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Generate tab component\n */\nfunction generateTabComponent(\n tab: { name: string; label: string; fields?: SchemaField[] },\n schema: Schema,\n generateFieldJSX: (field: SchemaField, indent?: string) => string,\n toPascalCase: (str: string) => string\n): string {\n const ir = getImportResolver()\n const tabPascalName = toPascalCase(tab.name)\n const tabFields = tab.fields || []\n\n // Recursive function to check for field types at any nesting level\n function checkForFieldType(fields: SchemaField[], type: string): boolean {\n for (const f of fields) {\n if (f.type === type) return true\n if (f.type === 'group' && f.fields) {\n if (checkForFieldType(f.fields, type)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForFieldType(f.fields, type)) return true\n }\n }\n return false\n }\n\n // Check what components are needed for this tab (recursively)\n const hasBooleanField = checkForFieldType(tabFields, 'boolean')\n const hasImageField = checkForFieldType(tabFields, 'image')\n const hasVideoField = checkForFieldType(tabFields, 'video')\n const hasMediaField = checkForFieldType(tabFields, 'media')\n const hasDateField = checkForFieldType(tabFields, 'date')\n const hasListField = checkForFieldType(tabFields, 'list')\n // Check for nested list fields (list fields that contain list fields in their nested fields)\n const hasNestedListField = tabFields.some(\n (f) => f.type === 'list' && f.fields?.some((nf) => nf.type === 'list')\n )\n const hasSelectField = checkForFieldType(tabFields, 'select')\n const hasMarkdownField = checkForFieldType(tabFields, 'markdown')\n const hasRichtextField = checkForFieldType(tabFields, 'richtext')\n const hasTextareaField = checkForFieldType(tabFields, 'text')\n const hasSeparatorField = checkForFieldType(tabFields, 'separator')\n const hasCurriculumField = checkForFieldType(tabFields, 'curriculum')\n\n // Check for icon type OR hasIcon property\n function checkForIconUsage(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'icon' || f.hasIcon) return true\n if (f.type === 'group' && f.fields) {\n if (checkForIconUsage(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForIconUsage(f.fields)) return true\n }\n }\n return false\n }\n const hasIconField = checkForIconUsage(tabFields)\n\n // Check for relationship fields\n function checkForRelationshipField(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'relationship') return true\n if (f.type === 'group' && f.fields) {\n if (checkForRelationshipField(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForRelationshipField(f.fields)) return true\n }\n }\n return false\n }\n const hasRelationshipField = checkForRelationshipField(tabFields)\n\n // Collect relationship fields for imports (only top-level and group fields, not inside lists)\n function collectRelationshipFieldsTopLevel(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n if (f.type === 'relationship' && f.relationship) result.push(f)\n if (f.type === 'group' && f.fields) {\n result.push(...collectRelationshipFieldsTopLevel(f.fields))\n }\n // Don't recurse into list fields - those use uncontrolled Popover\n }\n return result\n }\n // Collect ALL relationship fields (including those in lists) for data hooks\n function collectAllRelationshipFields(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n if (f.type === 'relationship' && f.relationship) result.push(f)\n if (f.type === 'group' && f.fields) {\n result.push(...collectAllRelationshipFields(f.fields))\n }\n if (f.type === 'list' && f.fields) {\n result.push(...collectAllRelationshipFields(f.fields))\n }\n }\n return result\n }\n const tabRelationshipFields = collectRelationshipFieldsTopLevel(tabFields)\n const tabAllRelationshipFields = collectAllRelationshipFields(tabFields)\n\n // Check for nested list fields in this tab\n const tabListFieldsWithNestedFields: SchemaField[] = []\n // Collect nested list fields (list fields inside list fields) with their parent info\n const tabNestedListFields: { parent: SchemaField; nested: SchemaField }[] = []\n function collectTabListFields(fields: SchemaField[]) {\n fields.forEach((f) => {\n if (f.type === 'list' && f.fields && f.fields.length > 0) {\n tabListFieldsWithNestedFields.push(f)\n // Check for nested lists inside this list field\n f.fields.forEach((nf) => {\n if (nf.type === 'list' && nf.fields && nf.fields.length > 0) {\n tabNestedListFields.push({ parent: f, nested: nf })\n }\n })\n }\n if (f.type === 'group' && f.fields) {\n collectTabListFields(f.fields)\n }\n })\n }\n collectTabListFields(tabFields)\n\n // Generate state for nested list accordions (using Record to track expanded state per parent index)\n // Use capitalize helper (not toPascalCase which lowercases rest of camelCase names)\n const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)\n const tabNestedListAccordionState = tabNestedListFields\n .map(\n ({ nested }) =>\n ` const [${nested.name}Expanded, set${capitalize(nested.name)}Expanded] = React.useState<Record<number, string | undefined>>({})`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n // Generate state for auto-opening relationship popovers when adding new nested list items\n const tabNestedListAutoOpenState = tabNestedListFields\n .filter(({ nested }) => nested.fields?.some((f) => f.type === 'relationship'))\n .map(\n ({ nested }) =>\n ` const [newlyAdded${capitalize(nested.name)}, setNewlyAdded${capitalize(nested.name)}] = React.useState<{ parentIndex: number; nestedIndex: number } | null>(null)`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n // Generate state for auto-opening relationship popovers when adding new regular list items (not nested lists)\n const tabListAutoOpenState = tabListFieldsWithNestedFields\n .filter((f) => f.fields?.some((nf) => nf.type === 'relationship'))\n .map(\n (field) =>\n ` const [newlyAdded${capitalize(field.name)}Item, setNewlyAdded${capitalize(field.name)}Item] = React.useState<number | null>(null)`\n )\n .filter((v, i, a) => a.indexOf(v) === i) // deduplicate\n .join('\\n')\n\n const tabFieldArrayHooks = [\n tabListFieldsWithNestedFields\n .map(\n (\n field\n ) => ` const [${field.name}Expanded, set${toPascalCase(field.name)}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 tabNestedListAccordionState,\n tabNestedListAutoOpenState,\n tabListAutoOpenState\n ]\n .filter(Boolean)\n .join('\\n')\n\n // Generate relationship open state (only for top-level, not inside lists)\n const tabRelationshipOpenState = tabRelationshipFields\n .map(\n (field) =>\n ` const [${field.name}Open, set${toPascalCase(field.name)}Open] = React.useState(false)`\n )\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')\n\n // Generate relationship data hooks (for ALL relationship fields including those in lists)\n const tabRelationshipDataHooks = [...new Set(tabAllRelationshipFields.map((f) => f.relationship))]\n .map((relationship) => {\n const relationshipPascal = toPascalCase(pluralize(relationship || ''))\n return ` const { data: ${relationship}Data } = use${relationshipPascal}()`\n })\n .join('\\n')\n\n const tabRelationshipHooks = [tabRelationshipOpenState, tabRelationshipDataHooks]\n .filter(Boolean)\n .join('\\n')\n\n // Helper to wrap top-level tab field with showWhen conditional\n const wrapTabFieldWithShowWhen = (fieldJSX: string, field: SchemaField, indent: string) => {\n if (!field.showWhen) return fieldJSX\n const showWhenField = field.showWhen.field\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(field.showWhen.value)) {\n const values = field.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch('${showWhenField}'))`\n } else if (field.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch('${showWhenField}') !== true`\n } else {\n showWhenCondition = `form.watch('${showWhenField}') === ${typeof field.showWhen.value === 'boolean' ? field.showWhen.value.toString() : `'${field.showWhen.value}'`}`\n }\n return `${indent}{${showWhenCondition} && (\n${fieldJSX}\n${indent})}`\n }\n\n const tabFieldsJSX = tabFields\n .map((field) => {\n const fieldJSX = generateFieldJSX(field, ' ')\n return wrapTabFieldWithShowWhen(fieldJSX, field, ' ')\n })\n .join('\\n')\n\n // Build imports for tab component\n const tabComponentImports = [\n 'FormControl',\n 'FormDescription',\n 'FormField',\n 'FormItem',\n 'FormLabel',\n 'FormMessage',\n 'Input'\n ]\n\n if (hasBooleanField) {\n tabComponentImports.push('Checkbox')\n }\n if (hasMarkdownField) {\n tabComponentImports.push('MarkdownEditor')\n }\n if (hasRichtextField) {\n tabComponentImports.push('RichTextEditor')\n }\n if (hasTextareaField) {\n tabComponentImports.push('Textarea')\n }\n if (hasImageField) {\n tabComponentImports.push('ImageUploadField')\n }\n if (hasVideoField) {\n tabComponentImports.push('VideoUploadField')\n }\n if (hasMediaField) {\n tabComponentImports.push('MediaUploadField')\n }\n if (hasDateField) {\n tabComponentImports.push('DatePicker')\n }\n if (hasCurriculumField) {\n tabComponentImports.push('CurriculumEditor')\n }\n if (hasIconField) {\n tabComponentImports.push('IconPicker')\n }\n if (hasListField) {\n tabComponentImports.push('Button', 'Label', 'Placeholder', 'Separator')\n if (tabListFieldsWithNestedFields.length > 0) {\n tabComponentImports.push('Accordion', 'AccordionContent', 'AccordionItem', 'AccordionTrigger')\n }\n }\n if (hasSeparatorField && !hasListField) {\n // Separator is already imported for list fields\n tabComponentImports.push('Separator')\n }\n if (hasSelectField) {\n tabComponentImports.push(\n 'Select',\n 'SelectContent',\n 'SelectItem',\n 'SelectTrigger',\n 'SelectValue'\n )\n }\n if (hasRelationshipField) {\n tabComponentImports.push(\n 'Button',\n 'Command',\n 'CommandEmpty',\n 'CommandGroup',\n 'CommandInput',\n 'CommandItem',\n 'CommandList',\n 'Popover',\n 'PopoverContent',\n 'PopoverTrigger'\n )\n }\n\n const tabLucideImports = (() => {\n const imports: string[] = []\n if (hasListField) imports.push('Plus', 'X')\n if (hasRelationshipField) imports.push('Check', 'ChevronsUpDown')\n if (hasNestedListField) imports.push('Trash2')\n return imports.length > 0\n ? `import { ${[...new Set(imports)].sort().join(', ')} } from 'lucide-react'`\n : ''\n })()\n const tabIconNameImport = hasIconField\n ? `import type { IconName } from 'lucide-react/dynamic'`\n : ''\n const tabMarkdownImport = hasMarkdownField\n ? `import { componentSnippets } from '${ir.libMarkdown}'`\n : ''\n const tabFieldArrayImport =\n tabListFieldsWithNestedFields.length > 0\n ? `import { useFieldArray } from 'react-hook-form'`\n : ''\n const tabRelationshipHooksImport =\n tabAllRelationshipFields.length > 0\n ? [...new Set(tabAllRelationshipFields.map((f) => f.relationship))]\n .map((relationship) => {\n const relationshipPascal = toPascalCase(pluralize(relationship || ''))\n return `import { use${relationshipPascal} } from '${ir.hooks}'`\n })\n .join('\\n')\n : ''\n const tabCnImport = hasRelationshipField ? `import { cn } from '${ir.utils}'` : ''\n\n const hasReactImport = tabListFieldsWithNestedFields.length > 0 || hasRelationshipField // Need React.useState for accordion state and combobox open state\n\n return `'use client'\n${hasReactImport ? `\\nimport * as React from 'react'` : ''}\nimport { UseFormReturn } from 'react-hook-form'${tabFieldArrayImport ? `\\n${tabFieldArrayImport}` : ''}${tabLucideImports ? `\\n${tabLucideImports}` : ''}${tabIconNameImport ? `\\n${tabIconNameImport}` : ''}${tabMarkdownImport ? `\\n${tabMarkdownImport}` : ''}${tabCnImport ? `\\n${tabCnImport}` : ''}${tabRelationshipHooksImport ? `\\n${tabRelationshipHooksImport}` : ''}\nimport {\n ${[...new Set(tabComponentImports)].sort().join(',\\n ')}\n} from '${ir.adminUi}'\nimport type { FormValues } from '../${schema.name}-form'\n\ninterface Tab${tabPascalName}Props {\n form: UseFormReturn<FormValues>\n isPending: boolean\n}\n\nexport function Tab${tabPascalName}({ form, isPending }: Tab${tabPascalName}Props) {\n${tabFieldArrayHooks ? `${tabFieldArrayHooks}\\n` : ''}${tabRelationshipHooks ? `${tabRelationshipHooks}\\n` : ''} return (\n <div className=\"space-y-5\">\n${tabFieldsJSX}\n </div>\n )\n}\n`\n}\n\n/**\n * Generate form component\n */\nexport async function generateForm(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const formFilePath = path.join(adminDir, `${schema.name}-form.tsx`)\n\n // Check if file exists\n if (fs.existsSync(formFilePath) && !options.force) {\n console.warn(` ⚠️ Form file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${schema.name}-form.tsx`\n }\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const camelSingular = toCamelCase(singularName)\n\n // Collect field names that are inside tabs (to avoid duplicates and unused hooks)\n const fieldsInTabs = new Set<string>()\n schema.fields.forEach((field) => {\n if (field.type === 'tabs' && field.tabs) {\n field.tabs.forEach((tab) => {\n if (tab.fields) {\n tab.fields.forEach((tabField) => {\n fieldsInTabs.add(tabField.name)\n // Also collect nested fields inside groups within tabs\n if (tabField.type === 'group' && tabField.fields) {\n tabField.fields.forEach((groupField) => {\n fieldsInTabs.add(groupField.name)\n // Check for nested list fields inside groups\n if (groupField.type === 'list' && groupField.fields) {\n groupField.fields.forEach((listField) => {\n fieldsInTabs.add(listField.name)\n })\n }\n })\n }\n // Check for nested list fields directly in tabs\n if (tabField.type === 'list' && tabField.fields) {\n tabField.fields.forEach((listField) => {\n fieldsInTabs.add(listField.name)\n })\n }\n })\n }\n })\n }\n })\n\n // Flatten fields for database operations (Zod schema and default values)\n // Include tabs so flattenFields can extract their nested fields, but we'll exclude tabs from Zod schema\n const allFieldsForSchema = schema.fields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'lastSynced'\n )\n const flatFields = flattenFields(allFieldsForSchema)\n\n // Generate Zod schema (exclude tabs - they're UI-only)\n const zodFields = flatFields\n .filter((field) => field.type !== 'tabs')\n .flatMap((field) => {\n const defs: string[] = []\n const zodType = getZodType(field)\n // Check if the zodType already includes .optional()\n const alreadyOptional = zodType.includes('.optional()')\n let zodDef = ` ${quotePropertyName(field.name)}: ${zodType}`\n // Only add .optional() if field is not required AND zodType doesn't already include it\n if (!field.required && !alreadyOptional) {\n zodDef += '.optional()'\n }\n defs.push(zodDef)\n // Add icon field if hasIcon is true\n if (field.hasIcon) {\n defs.push(` ${quotePropertyName(`${field.name}Icon`)}: z.string().optional()`)\n }\n return defs\n })\n .join(',\\n')\n\n // Helper function to check for markdown fields recursively (including inside lists)\n function checkForMarkdownField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'markdown') return true\n if (field.type === 'list' && field.fields) {\n if (checkForMarkdownField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForMarkdownField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForMarkdownField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Helper function to check for richtext fields recursively (including inside lists)\n function checkForRichtextField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'richtext') return true\n if (field.type === 'list' && field.fields) {\n if (checkForRichtextField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForRichtextField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForRichtextField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Helper function to check for text/textarea fields recursively (including inside lists)\n function checkForTextareaField(fields: SchemaField[]): boolean {\n for (const field of fields) {\n if (field.type === 'text') return true\n if (field.type === 'list' && field.fields) {\n if (checkForTextareaField(field.fields)) return true\n }\n if (field.type === 'group' && field.fields) {\n if (checkForTextareaField(field.fields)) return true\n }\n if (field.type === 'tabs' && field.tabs) {\n for (const tab of field.tabs) {\n if (tab.fields && checkForTextareaField(tab.fields)) return true\n }\n }\n }\n return false\n }\n\n // Check if we need ImageUploadField, DatePicker, DynamicListField, Select, or Tabs\n // Check both flatFields and schema.fields to catch fields in tabs\n const hasImageField =\n flatFields.some((f) => f.type === 'image') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'image'))\n ) ||\n schema.fields.some(\n (f) => f.type === 'list' && f.fields?.some((nested) => nested.type === 'image')\n )\n const hasVideoFieldMain =\n flatFields.some((f) => f.type === 'video') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'video'))\n )\n const hasMediaFieldMain =\n flatFields.some((f) => f.type === 'media') ||\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) => tab.fields?.some((field) => field.type === 'media'))\n )\n const hasDateField = flatFields.some((f) => f.type === 'date')\n\n // Check for relationship fields recursively\n function checkForRelationshipFieldMain(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'relationship') return true\n if (f.type === 'group' && f.fields) {\n if (checkForRelationshipFieldMain(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForRelationshipFieldMain(f.fields)) return true\n }\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields && checkForRelationshipFieldMain(tab.fields)) return true\n }\n }\n }\n return false\n }\n const hasRelationshipField = checkForRelationshipFieldMain(schema.fields)\n\n // Collect relationship fields for imports (only non-tab fields for main form)\n function collectRelationshipFieldsMain(fields: SchemaField[]): SchemaField[] {\n const result: SchemaField[] = []\n for (const f of fields) {\n // Skip tabs - they handle their own imports\n if (f.type === 'tabs') continue\n if (f.type === 'relationship' && f.relationship && !fieldsInTabs.has(f.name)) {\n result.push(f)\n }\n if (f.type === 'group' && f.fields) {\n result.push(...collectRelationshipFieldsMain(f.fields))\n }\n }\n return result\n }\n const mainRelationshipFields = collectRelationshipFieldsMain(schema.fields)\n // Check for icon type OR hasIcon property recursively\n function checkForIconUsageMain(fields: SchemaField[]): boolean {\n for (const f of fields) {\n if (f.type === 'icon' || f.hasIcon) return true\n if (f.type === 'group' && f.fields) {\n if (checkForIconUsageMain(f.fields)) return true\n }\n if (f.type === 'list' && f.fields) {\n if (checkForIconUsageMain(f.fields)) return true\n }\n if (f.type === 'tabs' && f.tabs) {\n for (const tab of f.tabs) {\n if (tab.fields && checkForIconUsageMain(tab.fields)) return true\n }\n }\n }\n return false\n }\n const hasIconField = checkForIconUsageMain(schema.fields)\n const hasListField = flatFields.some((f) => f.type === 'list')\n // Check for nested list fields (list fields that contain list fields in their nested fields)\n const hasNestedListField = flatFields.some(\n (f) => f.type === 'list' && f.fields?.some((nf) => nf.type === 'list')\n )\n const hasSeparatorFieldMain = flatFields.some((f) => f.type === 'separator')\n const hasSelectField = flatFields.some((f) => f.type === 'select')\n const hasMarkdownField = checkForMarkdownField(schema.fields)\n const hasRichtextField = checkForRichtextField(schema.fields)\n const hasTextareaField = checkForTextareaField(schema.fields)\n const tabsField = schema.fields.find((f) => f.type === 'tabs')\n const hasTabsField = !!tabsField\n const firstTabName = tabsField?.tabs?.[0]?.name || ''\n\n // Check if ALL fields are inside tabs (no standalone fields outside tabs)\n const allFieldsInTabs = (() => {\n const topLevelFields = schema.fields.filter(\n (f) =>\n !f.primaryKey &&\n f.name !== 'createdAt' &&\n f.name !== 'updatedAt' &&\n f.name !== 'lastSynced' &&\n f.name !== 'id'\n )\n return topLevelFields.length === 1 && topLevelFields[0].type === 'tabs'\n })()\n\n // Generate hint JSX if field has a hint\n function generateHintJSX(field: SchemaField, indent = ' '): string {\n if (!field.hint) return ''\n return `${indent} <FormDescription>${field.hint}</FormDescription>`\n }\n\n // Helper to wrap field JSX with showWhen conditional\n function wrapWithShowWhen(\n fieldJSX: string,\n field: SchemaField,\n indent: string,\n pathPrefix?: string\n ): string {\n if (!field.showWhen) return fieldJSX\n const showWhenField = field.showWhen.field\n const fieldPath = pathPrefix ? `\\`${pathPrefix}.${showWhenField}\\`` : `'${showWhenField}'`\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(field.showWhen.value)) {\n const values = field.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (field.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof field.showWhen.value === 'boolean' ? field.showWhen.value.toString() : `'${field.showWhen.value}'`}`\n }\n return `${indent}{${showWhenCondition} && (\n${fieldJSX}\n${indent})}`\n }\n\n // Generate a single form field JSX\n // pathPrefix is used for nested fields in lists (e.g., 'modules.${index}')\n function generateFieldJSX(\n field: SchemaField,\n indent = ' ',\n pathPrefix?: string\n ): string {\n // Hidden fields are not rendered in the form UI\n if (field.hidden) {\n return ''\n }\n\n const fieldType = getFormFieldType(field)\n const label = field.label || field.name\n const hintJSX = generateHintJSX(field, indent)\n\n // Handle group type - render nested fields in a grid\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields\n .map((nestedField) => {\n const nestedJSX = generateFieldJSX(nestedField, `${indent} `, pathPrefix)\n return wrapWithShowWhen(nestedJSX, nestedField, `${indent} `, pathPrefix)\n })\n .join('\\n')\n\n // Only show heading if label is set and not empty\n const headingJSX =\n label && label !== field.name\n ? `${indent}<h3 className=\"text-lg font-medium\">${label}</h3>\\n`\n : ''\n\n return `${indent}<div className=\"space-y-5\">\n${headingJSX}${indent} <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n${indent} </div>\n${indent}</div>`\n }\n\n // Handle separator type - render a visual separator\n if (field.type === 'separator') {\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\n if (field.type === 'image') {\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\n if (field.type === 'video') {\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\n if (field.type === 'media') {\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\n if (field.type === 'date') {\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\n if (field.type === 'select') {\n const options = field.options || []\n const optionsJSX = options\n .map(\n (opt) =>\n `${indent} <SelectItem key=\"${opt.value}\" value=\"${opt.value}\">${opt.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\n if (field.type === 'icon') {\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 as IconName | undefined}\n${indent} onValueChange={(value) => formField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (field.type === 'curriculum') {\n return `${indent}<FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormControl>\n${indent} <CurriculumEditor\n${indent} value={formField.value}\n${indent} onChange={formField.onChange}\n${indent} disabled={isPending}\n${indent} label=\"${label}\"\n${field.hint ? `${indent} hint=\"${field.hint}\"\\n` : ''}${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (field.type === 'relationship' && field.relationship) {\n const relationshipName = field.relationship\n const relationshipSingular = singularize(relationshipName)\n const relationshipPascal = toPascalCase(relationshipSingular)\n\n // Generate display field logic based on relationship type\n // For instructors: use firstName + lastName\n // For others: try name, title, or label\n let displayField: string\n if (relationshipName === 'instructors') {\n displayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else {\n // Generic fallback for other relationships - use 'in' type narrowing with string cast for type safety\n displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n\n // Access the array from the response object (e.g., instructorsData?.instructors)\n const dataArray = `${relationshipName}Data?.${relationshipName}`\n\n // Many-to-many relationship - multi-select UI\n if (field.multiple) {\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} <div className=\"flex gap-2\">\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} aria-expanded={${field.name}Open}\n${indent} className={cn(\n${indent} \"w-full justify-between min-h-10 h-auto\",\n${indent} (!formField.value || formField.value.length === 0) && \"text-muted-foreground\"\n${indent} )}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value && formField.value.length > 0\n${indent} ? (() => {\n${indent} const selectedItems = ${dataArray}?.filter((item) => \n${indent} item.id !== null && formField.value?.includes(item.id as number)\n${indent} ) || []\n${indent} if (selectedItems.length === 0) return \"Select ${label.toLowerCase()}\"\n${indent} if (selectedItems.length <= 2) {\n${indent} return selectedItems.map(item => ${displayField}).join(', ')\n${indent} }\n${indent} return \\`\\${selectedItems.length} ${label.toLowerCase()} selected\\`\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 ${relationshipSingular} 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 currentValue = formField.value || []\n${indent} const newValue = isSelected\n${indent} ? currentValue.filter((id: number) => id !== item.id)\n${indent} : [...currentValue, item.id as number]\n${indent} formField.onChange(newValue)\n${indent} }}\n${indent} >\n${indent} <Check\n${indent} className={cn(\n${indent} \"mr-2 size-4\",\n${indent} isSelected ? \"opacity-100\" : \"opacity-0\"\n${indent} )}\n${indent} />\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${indent} </div>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n // Single-value relationship - single-select combobox\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} aria-expanded={${field.name}Open}\n${indent} className={cn(\n${indent} \"w-full justify-between\",\n${indent} !formField.value && \"text-muted-foreground\"\n${indent} )}\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 ${relationshipSingular} 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\n${indent} className={cn(\n${indent} \"mr-2 size-4\",\n${indent} formField.value === String(item.id) ? \"opacity-100\" : \"opacity-0\"\n${indent} )}\n${indent} />\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\n if (field.type === 'list') {\n // Handle list with nested fields (array of objects)\n if (field.fields && field.fields.length > 0) {\n const nestedFieldsJSX = field.fields\n .map((nestedField) => {\n const nestedLabel = nestedField.label || nestedField.name\n const nestedFieldType = getFormFieldType(nestedField)\n\n // Handle nested list (list inside list)\n if (\n nestedField.type === 'list' &&\n nestedField.fields &&\n nestedField.fields.length > 0\n ) {\n const nestedListFields = nestedField.fields\n const nestedListLabel = nestedLabel\n const nestedListSingular = singularize(nestedListLabel)\n const nestedListDefaultValues = nestedListFields\n .map((f) => {\n // Use empty string for string-like fields to prevent uncontrolled-to-controlled warnings\n const isStringLike = [\n 'string',\n 'varchar',\n 'text',\n 'select',\n 'time',\n 'icon'\n ].includes(f.type)\n const isBoolean = f.type === 'boolean'\n // Use schema-defined default if available\n let defaultValue: string\n if (f.default !== undefined) {\n defaultValue =\n typeof f.default === 'string' ? `'${f.default}'` : String(f.default)\n } else if (isStringLike) {\n defaultValue = \"''\"\n } else if (isBoolean) {\n defaultValue = 'false'\n } else if (f.required) {\n defaultValue = \"''\"\n } else {\n defaultValue = 'undefined'\n }\n return `${quotePropertyName(f.name)}: ${defaultValue}`\n })\n .join(', ')\n // Helper to wrap nested list field with showWhen conditional\n const wrapWithShowWhen = (fieldJSX: string, nlf: SchemaField) => {\n if (!nlf.showWhen) return fieldJSX\n const showWhenField = nlf.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nlf.showWhen.value)) {\n const values = nlf.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nlf.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nlf.showWhen.value === 'boolean' ? nlf.showWhen.value.toString() : `'${nlf.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${fieldJSX}\n${indent} )}`\n }\n\n // Define nestedFieldCapitalized for use in nested list relationship fields\n const nestedFieldCapitalized =\n nestedField.name.charAt(0).toUpperCase() + nestedField.name.slice(1)\n\n const nestedListFieldsJSX = nestedListFields\n .map((nlf) => {\n const nlfLabel = nlf.label || nlf.name\n const nlfHint = nlf.hint\n ? `${indent} <FormDescription>${nlf.hint}</FormDescription>`\n : ''\n // Handle relationship fields in nested lists\n if (nlf.type === 'relationship' && nlf.relationship) {\n const relName = nlf.relationship\n const relSingular = singularize(relName)\n const relPascal = toPascalCase(relSingular)\n // selectedRelDisplayField uses selectedItem (for the button display)\n // relDisplayField uses item (for the map loop)\n let selectedRelDisplayField: string\n let relDisplayField: string\n if (relName === 'instructors') {\n selectedRelDisplayField = `(selectedItem.firstName && selectedItem.lastName ? \\`\\${selectedItem.firstName} \\${selectedItem.lastName}\\`.trim() : selectedItem.firstName || selectedItem.lastName || \\`${relPascal} \\${selectedItem.id ?? 'Unknown'}\\`)`\n relDisplayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else if (relName === 'posts') {\n selectedRelDisplayField = `(selectedItem.title || \\`Post \\${selectedItem.id ?? 'Unknown'}\\`)`\n relDisplayField = `(item.title || \\`Post \\${item.id ?? 'Unknown'}\\`)`\n } else {\n selectedRelDisplayField = `(('name' in selectedItem && selectedItem.name) || ('title' in selectedItem && selectedItem.title) || ('label' in selectedItem && selectedItem.label) || \\`${relPascal} \\${selectedItem.id ?? 'Unknown'}\\`) as string`\n relDisplayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n const relDataArray = `${relName}Data?.${relName}`\n const relFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <Popover\n${indent} open={newlyAdded${nestedFieldCapitalized}?.parentIndex === index && newlyAdded${nestedFieldCapitalized}?.nestedIndex === nestedIndex ? true : undefined}\n${indent} onOpenChange={(open) => { if (!open) setNewlyAdded${nestedFieldCapitalized}(null) }}\n${indent} >\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 selectedItem = ${relDataArray}?.find((item) => item.id !== null && String(item.id) === String(formField.value))\n${indent} return selectedItem ? ${selectedRelDisplayField} : \"Select ${nlfLabel.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${nlfLabel.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 h-4 w-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 ${nlfLabel.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${nlfLabel.toLowerCase()} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${relDataArray}?.map((item) => (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={${relDisplayField}}\n${indent} onSelect={() => {\n${indent} formField.onChange(item.id !== null ? String(item.id) : '')\n${indent} setNewlyAdded${nestedFieldCapitalized}(null)\n${indent} }}\n${indent} >\n${indent} <Check className={cn(\"mr-2 h-4 w-4\", item.id !== null && String(item.id) === String(formField.value) ? \"opacity-100\" : \"opacity-0\")} />\n${indent} {${relDisplayField}}\n${indent} </CommandItem>\n${indent} ))}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(relFieldJSX, nlf)\n }\n // Handle text fields as textarea\n if (nlf.type === 'text') {\n const textFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${nlfLabel.toLowerCase()}\"\n${indent} className=\"min-h-[60px] resize-y\"\n${indent} disabled={isPending}\n${indent} {...nestedListField}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(textFieldJSX, nlf)\n }\n // Handle boolean fields as checkbox\n if (nlf.type === 'boolean') {\n const booleanFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={nestedListField.value === true}\n${indent} onCheckedChange={nestedListField.onChange}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel className=\"cursor-pointer\">${nlfLabel}</FormLabel>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} </div>\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(booleanFieldJSX, nlf)\n }\n // Handle image fields with ImageUploadField\n if (nlf.type === 'image') {\n const imageFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={nestedListField.value || ''}\n${indent} onChange={nestedListField.onChange}\n${indent} onBlur={nestedListField.onBlur}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(imageFieldJSX, nlf)\n }\n // Default: string fields as input\n const stringFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nlf.name}\\`}\n${indent} render={({ field: nestedListField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nlfLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"text\"\n${indent} placeholder=\"Enter ${nlfLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} {...nestedListField}\n${indent} />\n${indent} </FormControl>\n${nlfHint ? `${nlfHint}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n return wrapWithShowWhen(stringFieldJSX, nlf)\n })\n .join('\\n')\n\n // Find a display field for the accordion title (prefer 'title', then relationship field's title, then first string field)\n const stringLikeTypes = ['string', 'varchar', 'text']\n const nestedListTitleField =\n nestedListFields.find((f) => f.name === 'title' && !f.showWhen) ||\n nestedListFields.find((f) => stringLikeTypes.includes(f.type) && !f.showWhen)\n const nestedListRelationshipField = nestedListFields.find(\n (f) => f.type === 'relationship' && !f.showWhen\n )\n // For auto-open popover feature, detect any relationship field (even with showWhen)\n const hasNestedListRelationship = nestedListFields.some(\n (f) => f.type === 'relationship'\n )\n\n // Check for conditional title pattern with relationship fallback\n const nestedListConditionalTitleField = nestedListFields.find(\n (f) => stringLikeTypes.includes(f.type) && f.showWhen?.value === true\n )\n // Find relationship with same toggle as title (original pattern)\n const nestedListConditionalRelationshipField = nestedListConditionalTitleField\n ? nestedListFields.find(\n (f) =>\n f.type === 'relationship' &&\n f.showWhen?.field === nestedListConditionalTitleField.showWhen?.field &&\n f.showWhen?.value === false\n )\n : null\n // Find any relationship field for title display (new pattern for different toggles)\n const nestedListAnyRelationshipField = nestedListFields.find(\n (f) => f.type === 'relationship'\n )\n\n let nestedListTitleExpression: string\n if (nestedListTitleField) {\n nestedListTitleExpression = `form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${nestedListTitleField.name}\\`) || \\`${nestedListSingular} \\${nestedIndex + 1}\\``\n } else if (\n nestedListConditionalTitleField &&\n nestedListConditionalRelationshipField?.relationship\n ) {\n // Handle conditional title: check toggle, use custom title or relationship title (same toggle)\n const toggleField = nestedListConditionalTitleField.showWhen?.field\n const customTitleFieldName = nestedListConditionalTitleField.name\n const relName = nestedListConditionalRelationshipField.relationship\n const relFieldName = nestedListConditionalRelationshipField.name\n nestedListTitleExpression = `(() => {\n const isCustom = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${toggleField}\\`)\n if (isCustom) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${customTitleFieldName}\\`)\n return customTitle || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else if (\n nestedListConditionalTitleField &&\n nestedListAnyRelationshipField?.relationship\n ) {\n // Handle conditional title with separate relationship toggle (different toggles)\n const overrideToggleField = nestedListConditionalTitleField.showWhen?.field\n const customTitleFieldName = nestedListConditionalTitleField.name\n const relName = nestedListAnyRelationshipField.relationship\n const relFieldName = nestedListAnyRelationshipField.name\n nestedListTitleExpression = `(() => {\n const isOverride = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${overrideToggleField}\\`)\n if (isOverride) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${customTitleFieldName}\\`)\n if (customTitle) return customTitle\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else if (nestedListRelationshipField?.relationship) {\n // Use the selected relationship item's display field (title, name, or slug as fallback)\n const relName = nestedListRelationshipField.relationship\n const relFieldName = nestedListRelationshipField.name\n nestedListTitleExpression = `(() => {\n const selectedId = form.watch(\\`${field.name}.\\${index}.${nestedField.name}.\\${nestedIndex}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || \\`${nestedListSingular} \\${nestedIndex + 1}\\`\n })()`\n } else {\n nestedListTitleExpression = `\\`${nestedListSingular} \\${nestedIndex + 1}\\``\n }\n const nestedListJSX = `${indent} <div className=\"space-y-2 bg-background rounded-md corner-squircle p-4 border border-border\">\n${indent} <div className=\"flex items-center justify-between\">\n${indent} <Label>${nestedListLabel}</Label>\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, [...current, { ${nestedListDefaultValues} }])\n${indent} const newNestedIndex = current.length\n${indent} set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: \\`item-\\${newNestedIndex + 1}\\` }))${\n hasNestedListRelationship\n ? `\n${indent} setNewlyAdded${nestedFieldCapitalized}({ parentIndex: index, nestedIndex: newNestedIndex })`\n : ''\n }\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${nestedListSingular}\n${indent} </Button>\n${indent} </div>\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).length > 0 && (\n${indent} <Accordion\n${indent} type=\"single\"\n${indent} collapsible\n${indent} className=\"w-full gap-1 flex flex-col\"\n${indent} value={${nestedField.name}Expanded[index]}\n${indent} onValueChange={(value) => set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: value }))}\n${indent} >\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).map((_: unknown, nestedIndex: number) => (\n${indent} <AccordionItem\n${indent} key={\\`${field.name}-\\${index}-${nestedField.name}-\\${nestedIndex}\\`}\n${indent} value={\\`item-\\${nestedIndex + 1}\\`}\n${indent} className=\"p-0 border-none\"\n${indent} >\n${indent} <div className=\"space-y-3 rounded-lg corner-squircle border p-3 bg-card\">\n${indent} <AccordionTrigger className=\"flex items-center p-0 justify-between w-full\">\n${indent} <div className=\"flex items-center gap-2\">\n${indent} <span className=\"text-xs font-medium text-muted-foreground\">{nestedIndex + 1}</span>\n${indent} <h4 className=\"text-sm font-medium\">{${nestedListTitleExpression}}</h4>\n${indent} </div>\n${indent} <Button asChild variant=\"ghost\" size=\"sm\" disabled={isPending} className=\"ml-auto\">\n${indent} <span\n${indent} role=\"button\"\n${indent} tabIndex={0}\n${indent} onClick={(e) => {\n${indent} e.stopPropagation()\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, current.filter((_: unknown, i: number) => i !== nestedIndex))\n${indent} }}\n${indent} onKeyDown={(e) => {\n${indent} if (e.key === 'Enter' || e.key === ' ') {\n${indent} e.preventDefault()\n${indent} e.stopPropagation()\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, current.filter((_: unknown, i: number) => i !== nestedIndex))\n${indent} }\n${indent} }}\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-3 pt-2\">\n${indent} <Separator />\n${nestedListFieldsJSX}\n${indent} </AccordionContent>\n${indent} </div>\n${indent} </AccordionItem>\n${indent} ))}\n${indent} </Accordion>\n${indent} )}\n${indent} {(form.watch(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []).length > 5 && (\n${indent} <div className=\"flex justify-end items-center gap-2\">\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"sm\"\n${indent} onClick={() => {\n${indent} const current = form.getValues(\\`${field.name}.\\${index}.${nestedField.name}\\`) || []\n${indent} form.setValue(\\`${field.name}.\\${index}.${nestedField.name}\\`, [...current, { ${nestedListDefaultValues} }])\n${indent} const newNestedIndex = current.length\n${indent} set${nestedFieldCapitalized}Expanded(prev => ({ ...prev, [index]: \\`item-\\${newNestedIndex + 1}\\` }))${\n hasNestedListRelationship\n ? `\n${indent} setNewlyAdded${nestedFieldCapitalized}({ parentIndex: index, nestedIndex: newNestedIndex })`\n : ''\n }\n${indent} }}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${nestedListSingular}\n${indent} </Button>\n${indent} </div>\n${indent} )}\n${indent} </div>`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}) || '')`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${nestedListJSX}\n${indent} )}`\n }\n return nestedListJSX\n }\n\n const nestedHintJSX = nestedField.hint\n ? `${indent} <FormDescription>${nestedField.hint}</FormDescription>`\n : ''\n\n if (nestedFieldType === 'textarea') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Textarea\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} className=\"min-h-[80px] resize-y\"\n${indent} disabled={isPending}\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedFieldType === 'markdown') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <MarkdownEditor\n${indent} value={nestedField.value}\n${indent} onChange={nestedField.onChange}\n${indent} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} componentSnippets={componentSnippets}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedFieldType === 'richtext') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <RichTextEditor\n${indent} value={nestedField.value}\n${indent} onChange={nestedField.onChange}\n${indent} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n if (nestedField.type === 'icon') {\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={nestedField.value as IconName | undefined}\n${indent} onValueChange={(value) => nestedField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n }\n // Handle hasIcon for nested fields - render input with IconPicker as postfix\n if (nestedField.hasIcon) {\n const iconFieldName = `${nestedField.name}Icon`\n return `${indent} <div className=\"flex gap-2 items-end\">\n${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem className=\"flex-1\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${nestedFieldType}\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${iconFieldName}\\`}\n${indent} render={({ field: iconField }) => (\n${indent} <FormItem>\n${indent} <FormLabel className=\"invisible\">Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={iconField.value as IconName | undefined}\n${indent} onValueChange={(value) => iconField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent} </div>`\n }\n // Handle checkbox for nested fields\n if (nestedFieldType === 'checkbox') {\n const checkboxJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem className=\"flex flex-row items-start space-x-3 space-y-0 rounded-md corner-squircle border p-4\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={nestedField.value === true}\n${indent} onCheckedChange={nestedField.onChange}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${nestedHintJSX ? `${nestedHintJSX.replace(`${indent} `, `${indent} `)}\\n` : ''}${indent} </div>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${checkboxJSX}\n${indent} )}`\n }\n return checkboxJSX\n }\n // Handle relationship fields inside nested lists\n if (nestedField.type === 'relationship' && nestedField.relationship) {\n const relationshipName = nestedField.relationship\n const relationshipSingular = singularize(relationshipName)\n const relationshipPascal = toPascalCase(relationshipSingular)\n\n // Generate display field logic based on relationship type\n // selectedDisplayField uses selectedItem (for the button display)\n // displayField uses item (for the map loop)\n let selectedDisplayField: string\n let displayField: string\n if (relationshipName === 'instructors') {\n selectedDisplayField = `(selectedItem.firstName && selectedItem.lastName ? \\`\\${selectedItem.firstName} \\${selectedItem.lastName}\\`.trim() : selectedItem.firstName || selectedItem.lastName || \\`${relationshipPascal} \\${selectedItem.id ?? 'Unknown'}\\`)`\n displayField = `(item.firstName && item.lastName ? \\`\\${item.firstName} \\${item.lastName}\\`.trim() : item.firstName || item.lastName || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`)`\n } else if (relationshipName === 'posts') {\n selectedDisplayField = `(selectedItem.title || \\`Post \\${selectedItem.id ?? 'Unknown'}\\`)`\n displayField = `(item.title || \\`Post \\${item.id ?? 'Unknown'}\\`)`\n } else {\n selectedDisplayField = `(('name' in selectedItem && selectedItem.name) || ('title' in selectedItem && selectedItem.title) || ('label' in selectedItem && selectedItem.label) || \\`${relationshipPascal} \\${selectedItem.id ?? 'Unknown'}\\`) as string`\n displayField = `(('name' in item && item.name) || ('title' in item && item.title) || ('label' in item && item.label) || \\`${relationshipPascal} \\${item.id ?? 'Unknown'}\\`) as string`\n }\n\n const dataArray = `${relationshipName}Data?.${relationshipName}`\n // Use simple capitalize (first char uppercase, rest unchanged) to match state generation\n const listCapitalizedName = field.name.charAt(0).toUpperCase() + field.name.slice(1)\n\n const relationshipJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex flex-col\">\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <Popover\n${indent} open={newlyAdded${listCapitalizedName}Item === index ? true : undefined}\n${indent} onOpenChange={(open) => { if (!open) setNewlyAdded${listCapitalizedName}Item(null) }}\n${indent} >\n${indent} <PopoverTrigger asChild>\n${indent} <FormControl>\n${indent} <Button\n${indent} variant=\"outline\"\n${indent} role=\"combobox\"\n${indent} className={cn(\n${indent} \"w-full justify-between\",\n${indent} !formField.value && \"text-muted-foreground\"\n${indent} )}\n${indent} disabled={isPending}\n${indent} >\n${indent} {formField.value\n${indent} ? (() => {\n${indent} const selectedItem = ${dataArray}?.find(\n${indent} (item) => item.id !== null && String(item.id) === String(formField.value)\n${indent} )\n${indent} return selectedItem ? ${selectedDisplayField} : \"Select ${nestedLabel.toLowerCase()}\"\n${indent} })()\n${indent} : \"Select ${nestedLabel.toLowerCase()}\"}\n${indent} <ChevronsUpDown className=\"ml-2 h-4 w-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 ${nestedLabel.toLowerCase()}...\" />\n${indent} <CommandList>\n${indent} <CommandEmpty>No ${nestedLabel.toLowerCase()} found.</CommandEmpty>\n${indent} <CommandGroup>\n${indent} {${dataArray}?.map((item) => (\n${indent} <CommandItem\n${indent} key={item.id}\n${indent} value={${displayField}}\n${indent} onSelect={() => {\n${indent} formField.onChange(item.id !== null ? String(item.id) : '')\n${indent} setNewlyAdded${listCapitalizedName}Item(null)\n${indent} }}\n${indent} >\n${indent} <Check\n${indent} className={cn(\n${indent} \"mr-2 h-4 w-4\",\n${indent} item.id !== null && String(item.id) === String(formField.value)\n${indent} ? \"opacity-100\"\n${indent} : \"opacity-0\"\n${indent} )}\n${indent} />\n${indent} {${displayField}}\n${indent} </CommandItem>\n${indent} ))}\n${indent} </CommandGroup>\n${indent} </CommandList>\n${indent} </Command>\n${indent} </PopoverContent>\n${indent} </Popover>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n // Handle array values (e.g., show when type is one of ['select', 'radio', 'checkbox'])\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n // For boolean false, use !== true to handle undefined initial state\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${relationshipJSX}\n${indent} )}`\n }\n return relationshipJSX\n }\n // Handle select fields inside lists\n if (nestedField.type === 'select' && nestedField.options) {\n const options = nestedField.options\n const optionsJSX = options\n .map(\n (opt) =>\n `${indent} <SelectItem key=\"${opt.value}\" value=\"${opt.value}\">${opt.label}</SelectItem>`\n )\n .join('\\n')\n const selectJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Select\n${indent} value={nestedField.value}\n${indent} onValueChange={nestedField.onChange}\n${indent} disabled={isPending}\n${indent} >\n${indent} <SelectTrigger>\n${indent} <SelectValue placeholder=\"Select ${nestedLabel.toLowerCase()}\" />\n${indent} </SelectTrigger>\n${indent} <SelectContent>\n${optionsJSX}\n${indent} </SelectContent>\n${indent} </Select>\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const fieldPath = `\\`${field.name}.\\${index}.${showWhenField}\\``\n let showWhenCondition: string\n if (Array.isArray(nestedField.showWhen.value)) {\n const values = nestedField.showWhen.value.map((v) => `'${v}'`).join(', ')\n showWhenCondition = `[${values}].includes(form.watch(${fieldPath}))`\n } else if (nestedField.showWhen.value === false) {\n showWhenCondition = `form.watch(${fieldPath}) !== true`\n } else {\n showWhenCondition = `form.watch(${fieldPath}) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n }\n return `${indent} {${showWhenCondition} && (\n${selectJSX}\n${indent} )}`\n }\n return selectJSX\n }\n // Handle group type fields (nested objects with sub-fields)\n if (\n nestedField.type === 'group' &&\n nestedField.fields &&\n nestedField.fields.length > 0\n ) {\n const groupFieldsJSX = nestedField.fields\n .map((groupField) => {\n const groupFieldLabel = groupField.label || groupField.name\n const groupFieldHintJSX = groupField.hint\n ? `${indent} <FormDescription>${groupField.hint}</FormDescription>`\n : ''\n const groupFieldType = getFormFieldType(groupField)\n return `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}.${groupField.name}\\`}\n${indent} render={({ field: groupFormField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${groupFieldLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${groupFieldType}\"\n${indent} placeholder=\"Enter ${groupFieldLabel.toLowerCase()}\"\n${indent} {...groupFormField}\n${indent} />\n${indent} </FormControl>\n${groupFieldHintJSX ? `${groupFieldHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n })\n .join('\\n')\n const groupJSX = `${indent} <div className=\"space-y-4\">\n${indent} <Label className=\"text-sm font-medium\">${nestedLabel}</Label>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <div className=\"pl-4 border-l-2 border-muted space-y-4\">\n${groupFieldsJSX}\n${indent} </div>\n${indent} </div>`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${groupJSX}\n${indent} )}`\n }\n return groupJSX\n }\n // Handle image fields inside lists\n if (nestedField.type === 'image') {\n const imageFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <ImageUploadField\n${indent} value={nestedField.value || ''}\n${indent} onChange={nestedField.onChange}\n${indent} onBlur={nestedField.onBlur}\n${indent} disabled={isPending}\n${indent} maxSizeInMB={10}\n${indent} label=\"\"\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${imageFieldJSX}\n${indent} )}`\n }\n return imageFieldJSX\n }\n // Default field handling\n const defaultFieldJSX = `${indent} <FormField\n${indent} control={form.control}\n${indent} name={\\`${field.name}.\\${index}.${nestedField.name}\\`}\n${indent} render={({ field: nestedField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>${nestedLabel}</FormLabel>\n${indent} <FormControl>\n${indent} <Input\n${indent} type=\"${nestedFieldType}\"\n${indent} placeholder=\"Enter ${nestedLabel.toLowerCase()}\"\n${indent} {...nestedField}\n${indent} />\n${indent} </FormControl>\n${nestedHintJSX ? `${nestedHintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent} />`\n // Wrap with showWhen conditional if specified\n if (nestedField.showWhen) {\n const showWhenField = nestedField.showWhen.field\n // For boolean false, use !== true to handle undefined initial state\n const showWhenCondition =\n nestedField.showWhen.value === false\n ? `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) !== true`\n : `form.watch(\\`${field.name}.\\${index}.${showWhenField}\\`) === ${typeof nestedField.showWhen.value === 'boolean' ? nestedField.showWhen.value.toString() : `'${nestedField.showWhen.value}'`}`\n return `${indent} {${showWhenCondition} && (\n${defaultFieldJSX}\n${indent} )}`\n }\n return defaultFieldJSX\n })\n .join('\\n')\n\n // Fix template strings to use actual field name and index\n const fixedNestedFieldsJSX = nestedFieldsJSX\n .replace(/\\$\\{field\\.name\\}/g, field.name)\n .replace(/\\$\\{index\\}/g, '$' + '{index}')\n\n const listHintJSX = field.hint\n ? `${indent} <FormDescription>${field.hint}</FormDescription>\\n`\n : ''\n\n const defaultValues = field.fields\n .flatMap((f) => {\n const defaults: string[] = []\n if (f.type === 'list' || f.type === 'curriculum') {\n defaults.push(\n `${quotePropertyName(f.name)}: ${f.type === 'curriculum' ? \"{ mode: 'sequential', items: [], weeks: [] }\" : '[]'}`\n )\n } else if (f.type === 'group' && f.fields && f.fields.length > 0) {\n // Generate default values for group sub-fields\n const groupDefaults = f.fields\n .map((gf) => {\n const isStringLike = ['string', 'varchar', 'text', 'select'].includes(gf.type)\n const isBoolean = gf.type === 'boolean'\n let gfDefault: string\n if (gf.default !== undefined) {\n gfDefault =\n typeof gf.default === 'string' ? `'${gf.default}'` : String(gf.default)\n } else if (isStringLike) {\n gfDefault = \"''\"\n } else if (isBoolean) {\n gfDefault = 'false'\n } else {\n gfDefault = 'undefined'\n }\n return `${quotePropertyName(gf.name)}: ${gfDefault}`\n })\n .join(', ')\n defaults.push(`${quotePropertyName(f.name)}: { ${groupDefaults} }`)\n } else {\n // Use empty string for string-like fields to prevent uncontrolled-to-controlled warnings\n const isStringLike = ['string', 'varchar', 'text', 'select', 'time', 'icon'].includes(\n f.type\n )\n const isNumber = ['number', 'serial', 'decimal'].includes(f.type)\n const isBoolean = f.type === 'boolean'\n // Use schema-defined default if available\n let defaultValue: string\n if (f.default !== undefined) {\n defaultValue = typeof f.default === 'string' ? `'${f.default}'` : String(f.default)\n } else if (isStringLike) {\n defaultValue = \"''\"\n } else if (isNumber) {\n defaultValue = '0'\n } else if (isBoolean) {\n defaultValue = 'false'\n } else if (f.required) {\n defaultValue = \"''\"\n } else {\n defaultValue = 'undefined'\n }\n defaults.push(`${quotePropertyName(f.name)}: ${defaultValue}`)\n }\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n defaults.push(`${quotePropertyName(`${f.name}Icon`)}: ''`)\n }\n return defaults\n })\n .join(', ')\n\n const singularLabel = singularize(label)\n const placeholderDescription =\n field.hint || `${label} is a list of items that can be added to the form.`\n\n // Find the first string-like field to use as accordion header (prioritize 'title' or 'name', then first text field, then relationship field)\n // Skip fields with showWhen conditions as they're not always visible\n const stringLikeTypes = ['string', 'varchar', 'text']\n const titleField =\n field.fields.find(\n (f) => f.name === 'title' && stringLikeTypes.includes(f.type) && !f.showWhen\n ) ||\n field.fields.find(\n (f) => f.name === 'name' && stringLikeTypes.includes(f.type) && !f.showWhen\n ) ||\n field.fields.find((f) => stringLikeTypes.includes(f.type) && !f.showWhen)\n // Find relationship field that's either unconditional or shows by default (showWhen.value === false)\n const relationshipField = field.fields.find(\n (f) => f.type === 'relationship' && (!f.showWhen || f.showWhen.value === false)\n )\n // For auto-open popover feature, detect any relationship field (even with showWhen)\n const hasAnyRelationshipField = field.fields?.some((f) => f.type === 'relationship')\n\n // Find conditional title field pattern: a string field shown when a toggle is true,\n // paired with a relationship shown when the same toggle is false\n const conditionalTitleField = field.fields.find(\n (f) =>\n stringLikeTypes.includes(f.type) &&\n f.showWhen?.value === true &&\n // Check if there's a matching relationship with opposite condition\n field.fields?.some(\n (rel) =>\n rel.type === 'relationship' &&\n rel.showWhen?.field === f.showWhen?.field &&\n rel.showWhen?.value === false\n )\n )\n const conditionalRelationshipField = conditionalTitleField\n ? field.fields.find(\n (f) =>\n f.type === 'relationship' &&\n f.showWhen?.field === conditionalTitleField.showWhen?.field &&\n f.showWhen?.value === false\n )\n : null\n\n let accordionTitle: string\n if (titleField) {\n accordionTitle = `{form.watch(\\`${field.name}.\\${index}.${titleField.name}\\`) || '${singularLabel} ' + (index + 1)}`\n } else if (conditionalTitleField && conditionalRelationshipField?.relationship) {\n // Handle conditional title: check toggle, use custom title or relationship title\n const toggleField = conditionalTitleField.showWhen?.field\n const customTitleFieldName = conditionalTitleField.name\n const relName = conditionalRelationshipField.relationship\n const relFieldName = conditionalRelationshipField.name\n accordionTitle = `{(() => {\n const isCustom = form.watch(\\`${field.name}.\\${index}.${toggleField}\\`)\n if (isCustom) {\n const customTitle = form.watch(\\`${field.name}.\\${index}.${customTitleFieldName}\\`)\n return customTitle || '${singularLabel} ' + (index + 1)\n }\n const selectedId = form.watch(\\`${field.name}.\\${index}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || '${singularLabel} ' + (index + 1)\n })()}`\n } else if (relationshipField?.relationship) {\n // Use the selected relationship item's display field (title, name, or slug as fallback)\n const relName = relationshipField.relationship\n const relFieldName = relationshipField.name\n accordionTitle = `{(() => {\n const selectedId = form.watch(\\`${field.name}.\\${index}.${relFieldName}\\`)\n const selectedItem = ${relName}Data?.${relName}?.find((item) => item.id !== null && String(item.id) === String(selectedId))\n const item = selectedItem as unknown as Record<string, unknown> | undefined\n return (item?.title as string) || (item?.name as string) || (item?.slug as string) || '${singularLabel} ' + (index + 1)\n })()}`\n } else {\n accordionTitle = `${singularLabel} {index + 1}`\n }\n\n const pascalFieldName = toPascalCase(field.name)\n // Use simple capitalize (first char uppercase, rest unchanged) to match state generation\n const capitalizedFieldName = field.name.charAt(0).toUpperCase() + field.name.slice(1)\n const dataAttrName = field.name.toLowerCase() // Data attributes must be lowercase\n const autoOpenLine = hasAnyRelationshipField\n ? `\\n${indent} setNewlyAdded${capitalizedFieldName}Item(newIndex - 1)`\n : ''\n const appendAndExpand = `{\n${indent} ${field.name}FieldArray.append({${defaultValues}})\n${indent} const newIndex = ${field.name}FieldArray.fields.length + 1\n${indent} set${pascalFieldName}Expanded(\\`item-\\${newIndex}\\`)${autoOpenLine}\n${indent} // Focus first input after accordion animation\n${indent} setTimeout(() => {\n${indent} const newItem = document.querySelector(\\`[data-${dataAttrName}-index=\"\\${newIndex - 1}\"] input\\`)\n${indent} if (newItem instanceof HTMLElement) newItem.focus()\n${indent} }, 100)\n${indent} }`\n\n return `${indent}<FormItem>\n${indent} {${field.name}FieldArray.fields.length === 0 && (\n${indent} <Placeholder\n${indent} label=\"No ${label.toLowerCase()} added yet. Click 'Add ${singularLabel}' to get started.\"\n${indent} description=\"${placeholderDescription}\"\n${indent} action={\n${indent} <Button\n${indent} type=\"button\"\n${indent} variant=\"outline\"\n${indent} size=\"lg\"\n${indent} onClick={() => ${appendAndExpand}}\n${indent} disabled={isPending}\n${indent} >\n${indent} <Plus />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} }\n${indent} />\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={() => ${appendAndExpand}}\n${indent} disabled={isPending || ${\n field.maxItems ? `${field.name}FieldArray.fields.length >= ${field.maxItems}` : 'false'\n }}\n${indent} >\n${indent} <Plus className='size-3' />\n${indent} Add ${singularLabel}\n${indent} </Button>\n${indent} </div>\n${listHintJSX ? listHintJSX : ''}${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} data-${dataAttrName}-index={index}\n${indent} >\n${indent} <div\n${indent} key={item.id}\n${indent} className=\"space-y-5 rounded-lg border p-4 bg-secondary/50 corner-squircle [&_h3]:m-0 w-full\"\n${indent} >\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) => {\n${indent} e.stopPropagation();\n${indent} ${field.name}FieldArray.remove(index);\n${indent} }}\n${indent} onKeyDown={(e) => {\n${indent} if (e.key === 'Enter' || e.key === ' ') {\n${indent} e.preventDefault();\n${indent} e.stopPropagation();\n${indent} ${field.name}FieldArray.remove(index);\n${indent} }\n${indent} }}\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\n${indent} <div className=\"space-y-5\">\n${fixedNestedFieldsJSX}\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 // Handle simple string list\n return `${indent}<DynamicListField\n${indent} name=\"${field.name}\"\n${indent} label=\"${label}\"\n${indent} disabled={isPending}\n${indent} ${field.maxItems ? `maxItems={${field.maxItems}}` : ''}\n${indent} placeholder=\"Enter ${field.items?.label?.toLowerCase() || 'value'}\"\n${indent}/>`\n }\n\n if (fieldType === 'checkbox') {\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 rounded-md corner-squircle border p-4\">\n${indent} <FormControl>\n${indent} <Checkbox\n${indent} checked={formField.value === true}\n${indent} onCheckedChange={formField.onChange}\n${indent} />\n${indent} </FormControl>\n${indent} <div className=\"space-y-1 leading-none\">\n${indent} <FormLabel>${label}</FormLabel>\n${hintJSX ? `${hintJSX.replace(`${indent} `, `${indent} `)}\\n` : ''}${indent} </div>\n${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (fieldType === 'textarea') {\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-[80px] resize-y\"\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\n if (fieldType === 'markdown') {\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} className=\"min-h-[200px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} componentSnippets={componentSnippets}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n if (fieldType === 'richtext') {\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-[200px]\"\n${indent} placeholder=\"Enter ${label.toLowerCase()}\"\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${hintJSX ? `${hintJSX}\\n` : ''}${indent} <FormMessage />\n${indent} </FormItem>\n${indent} )}\n${indent}/>`\n }\n\n // Handle hasIcon - render input with IconPicker as postfix\n if (field.hasIcon) {\n const iconFieldName = `${field.name}Icon`\n return `${indent}<div className=\"flex gap-2 items-end\">\n${indent} <FormField\n${indent} control={form.control}\n${indent} name=\"${field.name}\"\n${indent} render={({ field: formField }) => (\n${indent} <FormItem className=\"flex-1\">\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${indent} <FormField\n${indent} control={form.control}\n${indent} name=\"${iconFieldName}\"\n${indent} render={({ field: iconField }) => (\n${indent} <FormItem>\n${indent} <FormLabel>Icon</FormLabel>\n${indent} <FormControl>\n${indent} <IconPicker\n${indent} value={iconField.value as IconName | undefined}\n${indent} onValueChange={(value) => iconField.onChange(value ?? '')}\n${indent} disabled={isPending}\n${indent} />\n${indent} </FormControl>\n${indent} </FormItem>\n${indent} )}\n${indent} />\n${indent}</div>`\n }\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} <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 // Generate form fields with support for groups and tabs\n // Include tabs from schema.fields (not formFields since we filtered them out)\n const allFormFields = schema.fields.filter(\n (f) =>\n !f.primaryKey && f.name !== 'createdAt' && f.name !== 'updatedAt' && f.name !== 'lastSynced'\n )\n\n // Check for draft mode - published field is auto-added when draft mode is enabled\n const hasDraftMode = schema.actions?.draft === true\n const showDraftFeatures = hasDraftMode\n\n // Collect list fields with nested fields that need useFieldArray hooks\n // Only collect fields that are NOT inside tabs (tabs handle their own hooks)\n const listFieldsWithNestedFields: SchemaField[] = []\n\n function collectListFields(fields: SchemaField[]) {\n fields.forEach((f) => {\n if (f.type === 'list' && f.fields && f.fields.length > 0 && !f.hidden) {\n // Only add if not inside tabs (tabs handle their own hooks)\n if (!fieldsInTabs.has(f.name)) {\n listFieldsWithNestedFields.push(f)\n }\n }\n // Recursively check inside groups (but skip tabs since we already handled them)\n if (f.type === 'group' && f.fields) {\n collectListFields(f.fields)\n }\n // Skip tabs - they handle their own hooks\n })\n }\n\n collectListFields(allFormFields)\n\n // Generate useFieldArray hooks for list fields with nested fields (only those NOT in tabs)\n const fieldArrayHooks = listFieldsWithNestedFields\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 formFieldsJSX = allFormFields\n // Hide published field from form when draft mode is enabled (use Publish/Unpublish buttons instead)\n .filter((field) => !(showDraftFeatures && field.name === 'published'))\n .map((field) => {\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n\n const groupFields = field.fields\n .map((nestedField) => {\n const nestedJSX = generateFieldJSX(nestedField, ' ')\n return wrapWithShowWhen(nestedJSX, nestedField, ' ')\n })\n .join('\\n')\n\n const groupJSX = ` <div className=\"space-y-5\">\n <div className=\"grid ${gridClass} gap-4\">\n${groupFields}\n </div>\n </div>`\n // Wrap the entire group with showWhen if it has one\n return wrapWithShowWhen(groupJSX, field, ' ')\n }\n\n if (field.type === 'tabs' && field.tabs) {\n const tabsList = field.tabs\n .map((tab) => ` <TabsTrigger value=\"${tab.name}\">${tab.label}</TabsTrigger>`)\n .join('\\n')\n\n const tabsContent = field.tabs\n .map((tab) => {\n const tabPascalName = toPascalCase(tab.name)\n return ` <TabsContent value=\"${tab.name}\" className=\"space-y-6 p-6 rounded-2xl corner-squircle border bg-card\">\n <Tab${tabPascalName} form={form} isPending={isPending} />\n </TabsContent>`\n })\n .join('\\n')\n\n return ` <Tabs value={activeTab} onValueChange={setActiveTab} className=\"w-full\">\n <TabsList>\n${tabsList}\n </TabsList>\n${tabsContent}\n </Tabs>`\n }\n\n // Skip fields that are already inside tabs to avoid duplicates\n if (fieldsInTabs.has(field.name)) {\n return ''\n }\n\n const fieldJSX = generateFieldJSX(field)\n return wrapWithShowWhen(fieldJSX, field, ' ')\n })\n .filter((jsx) => jsx !== '') // Remove empty strings\n .join('\\n')\n\n // Build imports based on field types\n const componentImports = [\n 'Button',\n 'Form',\n 'FormControl',\n 'FormDescription',\n 'FormField',\n 'FormItem',\n 'FormLabel',\n 'FormMessage',\n 'Input'\n ]\n\n if (flatFields.some((f) => f.type === 'boolean')) {\n componentImports.push('Checkbox')\n }\n if (hasMarkdownField) {\n componentImports.push('MarkdownEditor')\n }\n if (hasRichtextField) {\n componentImports.push('RichTextEditor')\n }\n if (hasTextareaField) {\n componentImports.push('Textarea')\n }\n if (hasImageField) {\n componentImports.push('ImageUploadField')\n }\n if (hasVideoFieldMain) {\n componentImports.push('VideoUploadField')\n }\n if (hasMediaFieldMain) {\n componentImports.push('MediaUploadField')\n }\n if (hasDateField) {\n componentImports.push('DatePicker')\n }\n if (hasIconField) {\n componentImports.push('IconPicker')\n }\n if (hasSeparatorFieldMain && !hasListField) {\n // Separator is already imported for list fields\n componentImports.push('Separator')\n }\n if (hasListField) {\n componentImports.push('DynamicListField', 'Label', 'Placeholder', 'Separator')\n // Add Accordion components for list fields with nested fields\n // Check schema.fields directly (including inside tabs) for list fields with nested fields\n const hasListWithNestedFields = (() => {\n // Check top-level fields\n if (schema.fields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)) {\n return true\n }\n // Check inside tabs\n if (\n schema.fields.some(\n (f) =>\n f.type === 'tabs' &&\n f.tabs?.some((tab) =>\n tab.fields?.some(\n (field) => field.type === 'list' && field.fields && field.fields.length > 0\n )\n )\n )\n ) {\n return true\n }\n // Check inside groups\n if (\n schema.fields.some(\n (f) =>\n f.type === 'group' &&\n f.fields?.some(\n (field) => field.type === 'list' && field.fields && field.fields.length > 0\n )\n )\n ) {\n return true\n }\n return false\n })()\n if (hasListWithNestedFields) {\n componentImports.push('Accordion', 'AccordionContent', 'AccordionItem', 'AccordionTrigger')\n }\n }\n if (hasSelectField) {\n componentImports.push('Select', 'SelectContent', 'SelectItem', 'SelectTrigger', 'SelectValue')\n }\n if (hasTabsField) {\n componentImports.push('Tabs', 'TabsList', 'TabsTrigger', 'TabsContent')\n }\n if (hasRelationshipField) {\n componentImports.push(\n 'Command',\n 'CommandEmpty',\n 'CommandGroup',\n 'CommandInput',\n 'CommandItem',\n 'CommandList',\n 'Popover',\n 'PopoverContent',\n 'PopoverTrigger'\n )\n }\n\n // Generate relationship hook imports for main form\n const mainRelationshipHooksImport =\n mainRelationshipFields.length > 0\n ? mainRelationshipFields\n .map((f) => {\n const relationshipPascal = toPascalCase(pluralize(f.relationship || ''))\n return `import { use${relationshipPascal} } from '${ir.hooks}'`\n })\n .filter((v, i, a) => a.indexOf(v) === i) // Remove duplicates\n .join('\\n')\n : ''\n\n // Generate lucide imports\n const lucideImports = (() => {\n const imports: string[] = []\n if (hasListField) imports.push('Plus', 'X')\n if (hasRelationshipField) imports.push('Check', 'ChevronsUpDown')\n if (hasNestedListField) imports.push('Trash2')\n return imports.length > 0\n ? `\\nimport { ${[...new Set(imports)].sort().join(', ')} } from 'lucide-react'`\n : ''\n })()\n\n const needsReactImport =\n mainRelationshipFields.length > 0 || listFieldsWithNestedFields.length > 0\n\n const content = `'use client'\n${needsReactImport ? `\\nimport * as React from 'react'` : ''}\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'${lucideImports}${hasIconField ? `\\nimport type { IconName } from 'lucide-react/dynamic'` : ''}\nimport { useRouter } from 'next/navigation'\nimport {${listFieldsWithNestedFields.length > 0 ? ' useFieldArray,' : ''} useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'${hasTabsField ? `\\nimport { useQueryState } from 'nuqs'` : ''}${hasMarkdownField ? `\\nimport { componentSnippets } from '${ir.libMarkdown}'` : ''}${hasRelationshipField ? `\\nimport { cn } from '${ir.utils}'` : ''}${mainRelationshipHooksImport ? `\\n${mainRelationshipHooksImport}` : ''}\nimport {\n ${[...new Set(componentImports)].sort().join(',\\n ')}\n} from '${ir.adminUi}'${showDraftFeatures ? `\\nimport { use${pascalSingular} } from '${ir.hooks}'` : ''}\nimport type {\n Create${pascalSingular}Input,\n ${pascalSingular}Data,\n Update${pascalSingular}Input\n} from '${ir.actions(schema.name)}'\nimport { create${pascalSingular}, update${pascalSingular} } from '${ir.actions(schema.name)}'${\n hasTabsField && tabsField?.tabs\n ? `\\n${tabsField.tabs\n .map((tab) => {\n const tabPascalName = toPascalCase(tab.name)\n return `import { Tab${tabPascalName} } from './tabs/tab-${tab.name}'`\n })\n .join('\\n')}`\n : ''\n }\n\nconst formSchema = z.object({\n${zodFields}\n})\n\nexport type FormValues = z.infer<typeof formSchema>\n\ninterface ${pascalSingular}FormProps {\n initialData?: ${pascalSingular}Data\n}\n\nexport function ${pascalSingular}Form({ initialData }: ${pascalSingular}FormProps) {\n const router = useRouter()\n const queryClient = useQueryClient()${\n hasTabsField\n ? `\n const [activeTab, setActiveTab] = useQueryState('tab', { defaultValue: '${firstTabName}' })`\n : ''\n }${\n mainRelationshipFields.length > 0\n ? `\\n${mainRelationshipFields\n .map((f) => {\n const relationshipPascal = 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${relationshipPascal}()`\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .join('\\n')}`\n : ''\n }${\n showDraftFeatures\n ? `\n \n // Use React Query to fetch ${singularName} data if we have an ID - this will auto-update when cache is invalidated\n const { data: ${camelSingular}Data } = use${pascalSingular}(initialData?.id ?? null)\n \n // Use query data if available, otherwise fall back to initialData\n const ${camelSingular} = ${camelSingular}Data ?? initialData\n const published = ${camelSingular}?.published ?? false`\n : ''\n }\n\n const createMutation = useMutation({\n mutationFn: (data: Create${pascalSingular}Input) => create${pascalSingular}(data),\n onSuccess: async () => {\n toast.success('${pascalSingular} created successfully')\n await queryClient.invalidateQueries({ queryKey: ['${pluralName}'] })\n router.push('/admin/${schema.name}')\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to create ${singularName}')\n }\n })\n\n const updateMutation = useMutation({\n mutationFn: (data: Update${pascalSingular}Input) => update${pascalSingular}(data),\n onMutate: async (newData) => {\n // Optimistically update the cache\n if (initialData?.id) {\n queryClient.setQueryData(['${singularName}', initialData.id], (oldData: ${pascalSingular}Data | undefined) => {\n if (oldData) {\n return { ...oldData, ...newData${showDraftFeatures ? ', published: newData.published' : ''} }\n }\n return oldData\n })\n }\n },\n onSuccess: (data) => {\n toast.success('${pascalSingular} updated successfully')\n // Update the query cache with the server response\n if (data.${camelSingular} && initialData?.id) {\n queryClient.setQueryData(['${singularName}', initialData.id], data.${camelSingular})\n }\n // Invalidate list cache lazily - no await so UI stays responsive\n queryClient.invalidateQueries({ queryKey: ['${pluralName}'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update ${singularName}')\n }\n })\n\n const isPending = createMutation.isPending || updateMutation.isPending${\n showDraftFeatures\n ? `\n const isCreating = createMutation.isPending\n const isUpdating = updateMutation.isPending`\n : ''\n }\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${flatFields\n .filter((f) => f.type !== 'tabs')\n .flatMap((f) => {\n const defaults: string[] = []\n // Handle defaults based on field type\n if (f.type === 'list') {\n // Check if the list has nested relationship fields (direct or in nested lists) that need ID extraction\n const hasDirectRelationships = f.fields?.some((nf) => nf.type === 'relationship')\n const hasNestedListRelationships = f.fields?.some(\n (nf) => nf.type === 'list' && nf.fields?.some((nnf) => nnf.type === 'relationship')\n )\n const needsConversion = hasDirectRelationships || hasNestedListRelationships\n\n if (needsConversion && f.fields) {\n // Generate code to convert relationship objects to IDs\n const relationshipFields = f.fields.filter((nf) => nf.type === 'relationship')\n\n // Check if there are nested lists that also need conversion\n const nestedLists = f.fields.filter(\n (nf) => nf.type === 'list' && nf.fields?.some((nnf) => nnf.type === 'relationship')\n )\n\n const fieldConversions: string[] = []\n\n // Add conversions for direct relationship fields\n for (const rf of relationshipFields) {\n fieldConversions.push(\n ` ${rf.name}: item.${rf.name} ? (typeof item.${rf.name} === 'object' ? String((item.${rf.name} as { id: unknown }).id) : String(item.${rf.name})) : undefined`\n )\n }\n\n // Add conversions for nested list fields with relationships and booleans\n for (const nl of nestedLists) {\n const nestedRelFields = nl.fields!.filter((nnf) => nnf.type === 'relationship')\n const nestedBoolFields = nl.fields!.filter((nnf) => nnf.type === 'boolean')\n\n const nestedConversions: string[] = []\n\n // Handle relationship fields\n for (const nrf of nestedRelFields) {\n nestedConversions.push(\n ` ${nrf.name}: nestedItem.${nrf.name} ? (typeof nestedItem.${nrf.name} === 'object' ? String((nestedItem.${nrf.name} as { id: unknown }).id) : String(nestedItem.${nrf.name})) : undefined`\n )\n }\n\n // Handle boolean fields - coerce null/undefined to default (or false)\n for (const nbf of nestedBoolFields) {\n const defaultVal = nbf.default !== undefined ? String(nbf.default) : 'false'\n nestedConversions.push(\n ` ${nbf.name}: (nestedItem.${nbf.name} as boolean | null | undefined) ?? ${defaultVal}`\n )\n }\n\n const nestedConversionsStr = nestedConversions.join(',\\n')\n\n fieldConversions.push(` ${nl.name}: (item.${nl.name} as Record<string, unknown>[] | undefined)?.map((nestedItem: Record<string, unknown>) => ({\n ...nestedItem,\n${nestedConversionsStr}\n })) ?? []`)\n }\n\n defaults.push(` ${f.name}: initialData?.${f.name}?.map((item: Record<string, unknown>) => ({\n ...item,\n${fieldConversions.join(',\\n')}\n })) ?? []`)\n } else {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? []`)\n }\n } else if (f.type === 'curriculum') {\n // Curriculum fields are objects with mode and items/weeks\n defaults.push(` ${f.name}: initialData?.${f.name} ?? { mode: 'sequential', items: [] }`)\n } else if (f.type === 'boolean') {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? false`)\n } else if (f.type === 'number' || f.type === 'decimal' || f.type === 'serial') {\n const defaultVal = f.required ? '0' : 'undefined'\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ${defaultVal}`)\n } else if (f.type === 'relationship') {\n // Many-to-many relationships are arrays of IDs\n if (f.multiple) {\n defaults.push(` ${f.name}: initialData?.${f.name} ?? []`)\n } else {\n // Single relationship fields are strings (storing the ID as string)\n // But when fetched from the database, they may be objects (joined data)\n // So we need to extract the ID if it's an object\n defaults.push(` ${f.name}: initialData?.${f.name} \n ? (typeof initialData.${f.name} === 'object' ? String(initialData.${f.name}.id) : String(initialData.${f.name}))\n : ''`)\n }\n } else if (f.type === 'date' || f.type === 'timestamp') {\n // Date fields can use undefined since DatePicker handles it\n defaults.push(` ${f.name}: initialData?.${f.name} ?? undefined`)\n } else if (f.default !== undefined && f.default !== null) {\n // For string fields, check if there's a default value in schema\n const defaultStr = typeof f.default === 'string' ? `'${f.default}'` : f.default\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ${defaultStr}`)\n } else {\n // All other fields (string, varchar, text, select, time, image) use empty string\n defaults.push(` ${f.name}: initialData?.${f.name} ?? ''`)\n }\n // Add icon field if hasIcon is true\n if (f.hasIcon) {\n defaults.push(` ${f.name}Icon: initialData?.${f.name}Icon ?? ''`)\n }\n return defaults\n })\n .join(',\\n')}\n }\n })\n\n${fieldArrayHooks ? `${fieldArrayHooks}\\n` : ''}\n function onSubmit(values: FormValues${showDraftFeatures ? ', publishedValue: boolean = false' : ''}) {\n // Convert undefined to empty string for optional string fields to ensure proper serialization\n const cleanedValues = Object.fromEntries(\n Object.entries(values).map(([key, value]) => [\n key,\n value === undefined ? '' : value\n ])\n ) as FormValues\n \n if (initialData) {\n updateMutation.mutate({\n id: initialData.id as number,\n ...cleanedValues${showDraftFeatures ? ',\\n published: publishedValue' : ''}\n })\n } else {\n // Exclude id field when creating since it's not part of Create*Input types\n const { id: _id, ...createValues } = cleanedValues\n createMutation.mutate({\n ...createValues${showDraftFeatures ? ',\\n published: publishedValue' : ''}\n } as Create${pascalSingular}Input)\n }\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-form\" onSubmit={form.handleSubmit((values) => onSubmit(values${showDraftFeatures ? ', 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=\"${allFieldsInTabs ? 'space-y-6' : 'space-y-6 p-6 rounded-2xl corner-squircle 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('/admin/${schema.name}')}\n disabled={isPending}\n size=\"lg\"\n >\n Cancel\n </Button>\n${\n showDraftFeatures\n ? `\n {!initialData ? (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isCreating ? '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 {isCreating ? 'Publishing...' : 'Publish'}\n </Button>\n </>\n ) : published ? (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isUpdating ? 'Unpublishing...' : 'Unpublish'}\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 {isUpdating ? 'Updating...' : 'Update'}\n </Button>\n </>\n ) : (\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => form.handleSubmit((values) => onSubmit(values, false))()}\n disabled={isPending}\n size=\"lg\"\n >\n {isUpdating ? '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 {isUpdating ? 'Publishing...' : 'Publish'}\n </Button>\n </>\n )}`\n : `\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 // Generate tab component files if tabs exist\n if (hasTabsField && tabsField?.tabs) {\n const tabsDir = path.join(adminDir, 'tabs')\n ensureDir(tabsDir)\n\n tabsField.tabs.forEach((tab) => {\n const tabComponentPath = path.join(tabsDir, `tab-${tab.name}.tsx`)\n\n // Check if file exists\n if (fs.existsSync(tabComponentPath) && !options.force) {\n console.warn(\n ` ⚠️ Tab component file already exists: tab-${tab.name}.tsx. Use --force to overwrite.`\n )\n return\n }\n\n const tabComponentContent = generateTabComponent(tab, schema, generateFieldJSX, toPascalCase)\n\n fs.writeFileSync(tabComponentPath, tabComponentContent, 'utf-8')\n console.log(` ✓ Generated tab component: tabs/tab-${tab.name}.tsx`)\n })\n }\n\n fs.writeFileSync(formFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${schema.name}-form.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormColumn, FormField, FormSchema, GeneratorOptions } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n toCamelCase,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Check if a form schema has dynamicFields\n * Dynamic fields are stored in customFields JSON column\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n * Propagates group conditions to child fields\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[], parentCondition?: string): FormField[] => {\n return fields.flatMap((field) => {\n if (field.type === 'group' && field.fields) {\n // Combine parent condition with group condition\n const combinedCondition =\n parentCondition && field.condition\n ? `(${parentCondition}) && (${field.condition})`\n : parentCondition || field.condition\n // Recursively flatten group fields with inherited condition\n return flattenFields(field.fields, combinedCondition)\n }\n // For non-group fields, inherit the parent condition if field doesn't have its own\n if (parentCondition && !field.condition) {\n return [{ ...field, condition: parentCondition }]\n }\n // If field has its own condition and there's a parent condition, combine them\n if (parentCondition && field.condition) {\n return [{ ...field, condition: `(${parentCondition}) && (${field.condition})` }]\n }\n return field.type === 'group' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Generate custom column definition\n */\nfunction generateCustomColumnDef(col: FormColumn): string {\n const sortableHeader = col.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 ${col.header}, \\${sortLabel}\\`}\n aria-sort={sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'}\n >\n ${col.header}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n }`\n : `header: '${col.header}'`\n\n let cellDef = ''\n\n // Generate cell content based on column type\n const _cellContent = ''\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 * Generate admin page for form submissions\n */\nexport async function generateFormAdminPages(\n schema: FormSchema,\n _options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const formName = toCamelCase(schema.name)\n const kebabName = toKebabCase(schema.name)\n const pascalName = toPascalCase(schema.name)\n const pascalSubmissionName = `${pascalName}Submission`\n const pascalSubmissionsName = `${pascalName}Submissions`\n const submissionName = `${formName}Submission`\n\n // Admin page path: /admin/forms/<form-name>\n const adminPageDir = path.join(paths.app, `app/(admin)/admin/forms/${kebabName}`)\n ensureDir(adminPageDir)\n\n const fields = getAllFields(schema)\n\n // Generate page.tsx\n await generatePageComponent(adminPageDir, pascalSubmissionsName, kebabName)\n\n // Generate columns.tsx\n await generateColumnsComponent(\n adminPageDir,\n fields,\n pascalSubmissionName,\n submissionName,\n kebabName,\n schema.columns\n )\n\n // Generate submissions-table.tsx\n await generateTableComponent(\n adminPageDir,\n pascalSubmissionsName,\n pascalSubmissionName,\n submissionName,\n schema.label,\n kebabName\n )\n\n // Generate submissions-page-content.tsx\n await generatePageContentComponent(\n adminPageDir,\n pascalSubmissionsName,\n pascalSubmissionName,\n submissionName,\n schema.label,\n kebabName\n )\n\n // Generate view page (always generated)\n const includeDynamicFields = hasDynamicFields(schema)\n await generateViewPage(\n adminPageDir,\n pascalSubmissionName,\n fields,\n schema.label,\n kebabName,\n includeDynamicFields\n )\n\n // Generate settings page for webhook configuration\n await generateSettingsPage(adminPageDir, formName, schema.label, kebabName)\n\n console.log(` - Admin UI: apps/web/app/(admin)/admin/forms/${kebabName}/`)\n}\n\n/**\n * Generate page.tsx\n */\nasync function generatePageComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n kebabName: string\n): Promise<void> {\n const content = `import * as React from 'react'\nimport { AdminSubHeader } from '@/components/admin'\nimport { AdminPageSkeleton } from '@/components/admin/admin-page-skeleton'\nimport { ${pascalSubmissionsName}PageContent } from './${kebabName}-submissions-page-content'\nimport { columns } from './columns'\n\nexport default function Page() {\n return (\n <React.Suspense fallback={<AdminPageSkeleton />}>\n <div className=\"flex flex-col\">\n <AdminSubHeader />\n <${pascalSubmissionsName}PageContent columns={columns} />\n </div>\n </React.Suspense>\n )\n}\n`\n\n fs.writeFileSync(path.join(adminPageDir, 'page.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate columns.tsx with table columns definition\n */\nasync function generateColumnsComponent(\n adminPageDir: string,\n fields: FormField[],\n pascalSubmissionName: string,\n _submissionName: string,\n kebabName: string,\n customColumns?: FormColumn[]\n): Promise<void> {\n const ir = getImportResolver()\n // Generate column definitions - use custom columns if provided, otherwise auto-generate from fields\n const columnDefs = customColumns\n ? customColumns.map((col) => generateCustomColumnDef(col)).join(',\\n')\n : fields\n .filter((field) => field.name) // Filter out fields without names (like groups)\n .map((field) => {\n const accessor = toCamelCase(field.name!)\n const label = field.label\n\n return ` {\n accessorKey: '${accessor}',\n header: ({ column }) => {\n return (\n <Button\n variant=\"ghost\"\n onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n className=\"hover:bg-muted/50 px-0!\"\n >\n ${label}\n <ArrowUpDown className=\"size-4\" />\n </Button>\n )\n },\n cell: ({ row }) => {\n const value = row.getValue('${accessor}')\n return <div>${field.type === 'textarea' ? \"{value ? String(value).substring(0, 100) + (String(value).length > 100 ? '...' : '') : '-'}\" : \"{value || '-'}\"}</div>\n }\n }`\n })\n .join(',\\n')\n\n // Determine required imports based on column types\n const hasBadge = customColumns?.some((c) => c.type === 'badge') || false\n\n const content = `'use client'\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n ${hasBadge ? 'Badge,' : ''}\n Button,\n Checkbox\n} from '${ir.adminUi}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\nimport { delete${pascalSubmissionName} } from '${ir.actions(`${kebabName}-form`)}'\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 * as React from 'react'\nimport { toast } from 'sonner'\n\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${pascalSubmissionName}(id)\n\n if (result.success) {\n toast.success('Submission deleted successfully')\n // Refetch the list\n queryClient.refetchQueries({ queryKey: ['${kebabName}-submissions'] })\n setOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submission')\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 submission \\${id}\\`}>\n <Trash className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">Delete submission</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 submission.\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\nexport const columns: ColumnDef<${pascalSubmissionName}Data>[] = [\n {\n id: 'select',\n header: ({ table }) => (\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate')\n }\n onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => 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\" className=\"size-8\" asChild>\n <Link href={\\`/admin/forms/${kebabName}/\\${submission.id}/view\\`}>\n <Eye className=\"size-3\" strokeWidth={2} />\n <span className=\"sr-only\">View submission</span>\n </Link>\n </Button>\n <DeleteAction id={submission.id as number} />\n </div>\n )\n }\n }\n]\n`\n\n fs.writeFileSync(path.join(adminPageDir, 'columns.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate submissions-table.tsx with data table logic\n */\nasync function generateTableComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n pascalSubmissionName: string,\n _submissionName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const hookName = `use${pascalSubmissionsName}`\n\n const content = `'use client'\n\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '${ir.adminUi}'\nimport { ${hookName} } from '${ir.hooks}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\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'\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 ${pascalSubmissionsName}TableProps<TValue> {\n columns: ColumnDef<${pascalSubmissionName}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string\n}\n\nexport function ${pascalSubmissionsName}Table<TValue>({\n columns,\n selectedIds,\n setSelectedIds,\n search\n}: ${pascalSubmissionsName}TableProps<TValue>) {\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(10))\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(\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 } = ${hookName}(search)\n\n // Convert selectedIds array to rowSelection object format\n const rowSelection = React.useMemo(() => {\n const selection: Record<string, boolean> = {}\n const submissions = data?.submissions ?? []\n submissions.forEach((submission, index) => {\n if (selectedIds.includes(submission.id as number)) {\n selection[index.toString()] = true\n }\n })\n return selection\n }, [selectedIds, data?.submissions])\n\n // Handle row selection changes\n const handleRowSelectionChange = React.useCallback(\n (\n updater: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)\n ) => {\n const submissions = data?.submissions ?? []\n const newSelection = typeof updater === 'function' ? updater(rowSelection) : updater\n\n const newSelectedIds = Object.keys(newSelection)\n .filter((key) => newSelection[key])\n .map((key) => submissions[Number.parseInt(key, 10)]?.id as number)\n .filter(Boolean)\n\n setSelectedIds(newSelectedIds)\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: {\n pageIndex,\n pageSize: effectivePageSize\n }\n }\n })\n\n return (\n <div className=\"space-y-4\">\n <div className=\"bg-card border overflow-hidden rounded-lg corner-squircle\">\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 ${label} Submissions...</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 submissions: {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 submissions found.\n </TableCell>\n </TableRow>\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* Pagination */}\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((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 <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\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setPageIndex(Math.max(0, pageIndex - 1))}\n disabled={!table.getCanPreviousPage()}\n >\n Previous\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setPageIndex(pageIndex + 1)}\n disabled={!table.getCanNextPage()}\n >\n Next\n </Button>\n </div>\n </div>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(adminPageDir, `${kebabName}-submissions-table.tsx`), content, 'utf-8')\n}\n\n/**\n * Generate submissions-page-content.tsx with page header and actions\n */\nasync function generatePageContentComponent(\n adminPageDir: string,\n pascalSubmissionsName: string,\n pascalSubmissionName: string,\n _submissionName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const content = `'use client'\n\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Input\n} from '${ir.adminUi}'\nimport type { ${pascalSubmissionName}Data } from '${ir.actions(`${kebabName}-form`)}'\nimport { deleteBulk${pascalSubmissionsName} } from '${ir.actions(`${kebabName}-form`)}'\nimport { useQueryClient } from '@tanstack/react-query'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Search, Settings, Trash2 } from 'lucide-react'\nimport Link from 'next/link'\nimport { parseAsArrayOf, parseAsInteger, parseAsString, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\nimport { toast } from 'sonner'\nimport { AdminPageHeader } from '@/components/admin'\nimport { ${pascalSubmissionsName}Table } from './${kebabName}-submissions-table'\n\nfunction 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\ninterface ${pascalSubmissionsName}PageContentProps<TValue> {\n columns: ColumnDef<${pascalSubmissionName}Data, TValue>[]\n}\n\nexport function ${pascalSubmissionsName}PageContent<TValue>({\n columns\n}: ${pascalSubmissionsName}PageContentProps<TValue>) {\n const queryClient = useQueryClient()\n const [search, setSearch] = useQueryState('q', parseAsString.withDefault(''))\n\n const searchAction = React.useCallback(\n async (formData: FormData) => {\n const value = formData.get('search') as string\n React.startTransition(() => {\n setSearch(value || null)\n })\n },\n [setSearch]\n )\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${pascalSubmissionsName}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} submission\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${kebabName}-submissions'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete submissions')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n\n return (\n <>\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <AdminPageHeader title=\"${label}\" description=\"View and manage form submissions\" />\n <div className=\"flex items-center gap-2\">\n <form action={searchAction} className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"text-muted-foreground 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\"\n />\n </div>\n <SearchButton />\n </form>\n <Button variant=\"outline\" size=\"default\" asChild>\n <Link href=\"/admin/forms/${kebabName}/settings\">\n <Settings className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Settings\n </Link>\n </Button>\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} {selectedIds.length === 1 ? 'submission' : 'submissions'}\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 ? 'submission' : 'submissions'}.\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 </div>\n </div>\n\n <main className=\"space-y-4 p-5\">\n <${pascalSubmissionsName}Table\n columns={columns}\n selectedIds={selectedIds}\n setSelectedIds={setSelectedIds}\n search={search}\n />\n </main>\n </>\n )\n}\n`\n\n fs.writeFileSync(\n path.join(adminPageDir, `${kebabName}-submissions-page-content.tsx`),\n content,\n 'utf-8'\n )\n}\n\n/**\n * Generate view page for form submissions\n */\nasync function generateViewPage(\n adminPageDir: string,\n pascalSubmissionName: string,\n fields: FormField[],\n label: string,\n kebabName: string,\n includeDynamicFields: boolean\n): Promise<void> {\n const ir = getImportResolver()\n const viewPageDir = path.join(adminPageDir, '[id]/view')\n ensureDir(viewPageDir)\n\n // Check if any fields are upload/file type\n const hasUploadFields = fields.some((f) => f.type === 'upload' || f.type === 'file')\n\n // Generate field display items matching form field styling\n const fieldItems = fields\n .filter((f) => f.name) // Only fields with names\n .map((field) => {\n const fieldName = field.name || ''\n const fieldLabel = field.label\n\n // Handle different field types\n if (field.type === 'upload' || field.type === 'file') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm\">\n {submission.${fieldName} ? (\n <a\n href={submission.${fieldName}}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n download\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 hover:bg-secondary transition-colors\"\n >\n <Download className=\"size-4\" />\n Download File\n </a>\n ) : (\n <span className=\"text-muted-foreground\">No file uploaded</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'url') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? (\n <a\n href={submission.${fieldName}}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline break-all\"\n >\n {submission.${fieldName}}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'email') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? (\n <a\n href={\\`mailto:\\${submission.${fieldName}}\\`}\n className=\"text-primary hover:underline\"\n >\n {submission.${fieldName}}\n </a>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'textarea') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 whitespace-pre-wrap min-h-[80px]\">\n {submission.${fieldName} || <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n }\n\n if (field.type === 'list') {\n if (field.fields && field.fields.length > 0) {\n // Object list\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm\">\n {submission.${fieldName} && Array.isArray(submission.${fieldName}) && submission.${fieldName}.length > 0 ? (\n <div className=\"space-y-2\">\n {submission.${fieldName}.map((item: Record<string, unknown>, idx: number) => (\n <div key={idx} className=\"p-3 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {Object.entries(item).map(([key, value]) => (\n <div key={key} className=\"flex gap-2\">\n <span className=\"font-medium capitalize\">{key}:</span>\n <span>{String(value)}</span>\n </div>\n ))}\n </div>\n ))}\n </div>\n ) : (\n <div className=\"px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 text-muted-foreground\">-</div>\n )}\n </div>\n </div>`\n }\n // Simple string list\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} && Array.isArray(submission.${fieldName}) && submission.${fieldName}.length > 0 ? (\n <ul className=\"list-disc list-inside\">\n {submission.${fieldName}.map((item: string, idx: number) => (\n <li key={idx}>{item}</li>\n ))}\n </ul>\n ) : (\n <span className=\"text-muted-foreground\">-</span>\n )}\n </div>\n </div>`\n }\n\n if (field.type === 'checkbox') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? 'Yes' : 'No'}\n </div>\n </div>`\n }\n\n if (field.type === 'date') {\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ? new Date(submission.${fieldName}).toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' }) : <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n }\n\n // Default text display\n return ` <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">${fieldLabel}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {submission.${fieldName} ?? <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>`\n })\n .join('\\n')\n\n // Generate custom fields section for dynamic fields\n const customFieldsSection = includeDynamicFields\n ? `\n {/* Dynamic Fields (from CMS) */}\n {submission.customFields && Object.keys(submission.customFields).length > 0 && (\n <>\n <div className=\"border-t border-border my-4\" />\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-muted-foreground\">Custom Fields</p>\n </div>\n {Object.entries(submission.customFields).map(([key, value]) => (\n <div key={key} className=\"space-y-2\">\n <p className=\"text-sm font-medium capitalize\">{key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50 whitespace-pre-wrap\">\n {value !== null && value !== undefined ? String(value) : <span className=\"text-muted-foreground\">-</span>}\n </div>\n </div>\n ))}\n </>\n )}`\n : ''\n\n const content = `import { Button } from '${ir.adminUi}'\nimport { get${pascalSubmissionName} } from '${ir.actions(`${kebabName}-form`)}'\nimport { ArrowLeft${hasUploadFields ? ', Download' : ''} } from 'lucide-react'\nimport Link from 'next/link'\nimport { notFound } from 'next/navigation'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\n\ninterface PageProps {\n params: Promise<{\n id: string\n }>\n}\n\nexport default async function Page({ params }: PageProps) {\n const { id } = await params\n const submission = await get${pascalSubmissionName}(Number.parseInt(id, 10))\n\n if (!submission) {\n notFound()\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <AdminPageHeader title=\"${label} Submission\" description={\\`Viewing submission #\\${id}\\`} />\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">\n <ArrowLeft className=\"size-4\" />\n Back to ${label}\n </Link>\n </Button>\n </div>\n </div>\n <main className=\"container mx-auto max-w-5xl p-5\">\n <div className=\"space-y-5 px-7 pt-7 pb-8 rounded-2xl corner-squircle border bg-background\">\n${fieldItems}${customFieldsSection}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">Submitted At</p>\n <div className=\"text-sm px-3 py-2 rounded-lg corner-squircle border border-border bg-secondary/50\">\n {new Date(submission.submittedAt).toLocaleString('en-US', {\n month: 'long',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n })}\n </div>\n </div>\n </div>\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(viewPageDir, 'page.tsx'), content, 'utf-8')\n}\n\n/**\n * Generate settings page for form webhook configuration\n */\nasync function generateSettingsPage(\n adminPageDir: string,\n formName: string,\n label: string,\n kebabName: string\n): Promise<void> {\n const ir = getImportResolver()\n const settingsPageDir = path.join(adminPageDir, 'settings')\n ensureDir(settingsPageDir)\n\n const content = `'use client'\n\nimport {\n Button,\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n Input,\n Switch,\n Textarea\n} from '${ir.adminUi}'\nimport { getFormSettings, testFormWebhook, upsertFormSettings } from '${ir.actions('form-settings')}'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { ArrowLeft, Send } from 'lucide-react'\nimport Link from 'next/link'\nimport * as React from 'react'\nimport { useForm } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\nimport { AdminPageHeader, AdminSubHeader } from '@/components/admin'\n\nconst formSchema = z.object({\n notificationEmails: z.string().optional(),\n webhookUrl: z.string().url('Please enter a valid URL').or(z.literal('')),\n webhookEnabled: z.boolean()\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\nexport default function SettingsPage() {\n const [isPending, startTransition] = React.useTransition()\n const [isTestingWebhook, setIsTestingWebhook] = React.useState(false)\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n notificationEmails: '',\n webhookUrl: '',\n webhookEnabled: false\n }\n })\n\n // Load existing settings on mount\n React.useEffect(() => {\n const loadSettings = async () => {\n const settings = await getFormSettings('${formName}')\n if (settings) {\n form.reset({\n notificationEmails: settings.notificationEmails || '',\n webhookUrl: settings.webhookUrl || '',\n webhookEnabled: settings.webhookEnabled\n })\n }\n }\n loadSettings()\n }, [form])\n\n const onSubmit = (values: FormValues) => {\n startTransition(async () => {\n try {\n const result = await upsertFormSettings('${formName}', {\n notificationEmails: values.notificationEmails || null,\n webhookUrl: values.webhookUrl || null,\n webhookEnabled: values.webhookEnabled\n })\n\n if (result.success) {\n toast.success('Settings saved successfully')\n } else {\n toast.error(result.error || 'Failed to save settings')\n }\n } catch (error) {\n console.error('Error saving settings:', error)\n toast.error('An error occurred while saving settings')\n }\n })\n }\n\n const handleTestWebhook = async () => {\n const webhookUrl = form.getValues('webhookUrl')\n if (!webhookUrl) {\n toast.error('Please enter a webhook URL first')\n return\n }\n\n setIsTestingWebhook(true)\n try {\n // Save the URL first\n await upsertFormSettings('${formName}', {\n webhookUrl: webhookUrl || null\n })\n\n const result = await testFormWebhook('${formName}')\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 } catch (error) {\n console.error('Error testing webhook:', error)\n toast.error('An error occurred while testing the webhook')\n } finally {\n setIsTestingWebhook(false)\n }\n }\n\n return (\n <div className=\"flex flex-col w-full pb-20\">\n <div className=\"flex flex-col w-full sticky top-0 z-100\">\n <AdminSubHeader />\n <div className=\"flex items-center justify-between bg-background px-5 py-3 border-b border-border\">\n <div className=\"flex items-center gap-4\">\n <Button variant=\"outline\" size=\"icon\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">\n <ArrowLeft className=\"size-4\" />\n </Link>\n </Button>\n <AdminPageHeader\n title=\"${label} Settings\"\n description=\"Configure webhook and notification settings\"\n />\n </div>\n </div>\n </div>\n\n <main className=\"container mx-auto max-w-5xl p-5\">\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n <div className=\"space-y-6 px-7 pt-7 pb-8 rounded-2xl corner-squircle border bg-background\">\n <FormField\n control={form.control}\n name=\"notificationEmails\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Notification Emails</FormLabel>\n <FormControl>\n <Textarea\n placeholder=\"email1@example.com, email2@example.com\"\n className=\"min-h-[80px]\"\n {...field}\n />\n </FormControl>\n <FormDescription>\n Email addresses to receive notifications when form is submitted (comma-separated). Falls back to NOTIFICATION_EMAIL env var if empty.\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"webhookUrl\"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Webhook URL</FormLabel>\n <FormControl>\n <Input\n type=\"url\"\n placeholder=\"https://hooks.zapier.com/hooks/catch/...\"\n {...field}\n />\n </FormControl>\n <FormDescription>\n POST request will be sent to this URL when a form is submitted\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"webhookEnabled\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div className=\"space-y-0.5\">\n <FormLabel className=\"text-base\">Enable Webhook</FormLabel>\n <FormDescription>\n Send form submission data to the webhook URL\n </FormDescription>\n </div>\n <FormControl>\n <Switch\n checked={field.value}\n onCheckedChange={field.onChange}\n />\n </FormControl>\n </FormItem>\n )}\n />\n\n <div className=\"pt-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleTestWebhook}\n disabled={isTestingWebhook || !form.watch('webhookUrl')}\n >\n <Send className=\"mr-2 h-4 w-4\" />\n {isTestingWebhook ? 'Sending...' : 'Test Webhook'}\n </Button>\n </div>\n </div>\n\n <div className=\"fixed bottom-0 left-0 md:left-[calc(var(--sidebar-width))] right-0 border-t bg-background px-6 py-4\">\n <div className=\"container mx-auto max-w-5xl flex justify-end gap-2\">\n <Button variant=\"outline\" asChild>\n <Link href=\"/admin/forms/${kebabName}\">Cancel</Link>\n </Button>\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Saving...' : 'Save Settings'}\n </Button>\n </div>\n </div>\n </form>\n </Form>\n </main>\n </div>\n )\n}\n`\n\n fs.writeFileSync(path.join(settingsPageDir, 'page.tsx'), content, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormField, FormSchema, GeneratorOptions } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n toCamelCase,\n toPascalCase,\n toSnakeCase\n} from '../utils'\nimport { generateEmailTemplate } from './email-template'\nimport { generateFormAdminPages } from './form-admin-pages'\nimport { updateFormNavigation } from './form-navigation'\n\n/**\n * Check if a form schema has dynamicFields\n * Dynamic fields are stored in customFields JSON column\n */\nfunction hasDynamicFields(schema: FormSchema): boolean {\n const checkFields = (fields: FormField[]): boolean => {\n for (const field of fields) {\n if (field.type === 'dynamicFields') return true\n if (field.type === 'group' && field.fields && checkFields(field.fields)) return true\n }\n return false\n }\n\n if (schema.fields && checkFields(schema.fields)) return true\n if (schema.steps) {\n for (const step of schema.steps) {\n if (checkFields(step.fields)) return true\n }\n }\n return false\n}\n\n/**\n * Convert showWhen object to condition string\n * showWhen: { field: \"status\", value: \"active\" } -> \"status === 'active'\"\n * showWhen: { field: \"status\", value: [\"active\", \"pending\"] } -> \"['active', 'pending'].includes(status)\"\n */\nfunction showWhenToCondition(showWhen: {\n field: string\n value: boolean | string | number | (string | number)[]\n}): string {\n const { field, value } = showWhen\n if (Array.isArray(value)) {\n const values = value.map((v) => (typeof v === 'string' ? `'${v}'` : v)).join(', ')\n return `[${values}].includes(${field})`\n }\n if (typeof value === 'boolean') {\n return value ? `${field} === true` : `${field} !== true`\n }\n if (typeof value === 'string') {\n return `${field} === '${value}'`\n }\n return `${field} === ${value}`\n}\n\n/**\n * Get all fields from a form schema (flatten steps and groups)\n * Propagates group conditions to child fields\n * Skips dynamicFields since they have no database columns (rendered from CMS)\n */\nfunction getAllFields(schema: FormSchema): FormField[] {\n const flattenFields = (fields: FormField[], parentCondition?: string): FormField[] => {\n return fields.flatMap((field) => {\n // Skip dynamicFields - they don't have database columns (rendered from CMS)\n if (field.type === 'dynamicFields') {\n return []\n }\n\n // Convert showWhen to condition if present (and field doesn't have explicit condition)\n let fieldCondition = field.condition\n if (!fieldCondition && field.showWhen) {\n fieldCondition = showWhenToCondition(field.showWhen)\n }\n\n if (field.type === 'group' && field.fields) {\n // Combine parent condition with group condition\n const combinedCondition =\n parentCondition && fieldCondition\n ? `(${parentCondition}) && (${fieldCondition})`\n : parentCondition || fieldCondition\n // Recursively flatten group fields with inherited condition\n return flattenFields(field.fields, combinedCondition)\n }\n // For non-group fields, inherit the parent condition if field doesn't have its own\n if (parentCondition && !fieldCondition) {\n return [{ ...field, condition: parentCondition }]\n }\n // If field has its own condition and there's a parent condition, combine them\n if (parentCondition && fieldCondition) {\n return [{ ...field, condition: `(${parentCondition}) && (${fieldCondition})` }]\n }\n // If field has its own condition (from showWhen conversion), use it\n if (fieldCondition && !field.condition) {\n return [{ ...field, condition: fieldCondition }]\n }\n return field.type === 'group' ? [] : [field]\n })\n }\n\n if (schema.fields) {\n return flattenFields(schema.fields)\n }\n if (schema.steps) {\n return schema.steps.flatMap((step) => flattenFields(step.fields))\n }\n return []\n}\n\n/**\n * Generate email field HTML from schema fields, including dynamicFields inline\n * This iterates through the original schema fields to preserve ordering\n * and inserts customFields HTML at the position where dynamicFields appears\n */\nfunction _generateEmailFieldsHtml(schema: FormSchema): string {\n const processFields = (fields: FormField[]): string[] => {\n const htmlParts: string[] = []\n for (const field of fields) {\n if (field.type === 'dynamicFields') {\n // Insert dynamic/custom fields at this position\n htmlParts.push(`\\${data.customFields && Object.keys(data.customFields).length > 0\n ? Object.entries(data.customFields).map(([key, value]) => \\`\n <div style=\"margin-bottom: 16px;\">\n <p style=\"color: #666; font-size: 14px; font-weight: 600; margin: 0 0 4px 0;\">\\${key.replace(/([A-Z])/g, ' $1').trim()}</p>\n <p style=\"color: #333; font-size: 16px; margin: 0;\">\\${formatValue(value, 'text')}</p>\n </div>\n \\`).join('')\n : ''}`)\n } else if (field.type === 'group' && field.fields) {\n // Recursively process group fields\n htmlParts.push(...processFields(field.fields))\n } else if (field.name && field.label) {\n // Regular field\n htmlParts.push(`<div style=\"margin-bottom: 16px;\">\n <p style=\"color: #666; font-size: 14px; font-weight: 600; margin: 0 0 4px 0;\">${field.label}</p>\n <p style=\"color: #333; font-size: 16px; margin: 0;\">\\${formatValue(data.${field.name}, '${field.type}')}</p>\n </div>`)\n }\n }\n return htmlParts\n }\n\n const allFields =\n schema.fields || (schema.steps ? schema.steps.flatMap((step) => step.fields) : [])\n return processFields(allFields).join('\\n ')\n}\n\n/**\n * Generate props for the React Email component render call\n */\nfunction generateEmailPropsForRender(fields: FormField[], includeDynamicFields: boolean): string {\n const fieldProps = fields\n .filter((f) => f.name) // Only include fields with names\n .map((f) => `${f.name}: data.${f.name} ?? null,`)\n .join('\\n ')\n\n const customFieldsProp = includeDynamicFields\n ? '\\n customFields: data.customFields ?? null,'\n : ''\n\n return fieldProps + customFieldsProp\n}\n\n/**\n * Generate the name expression for email subject based on available fields\n */\nfunction getEmailSubjectNameExpr(fields: FormField[]): string {\n const fieldNames = fields.map((f) => f.name)\n const hasName = fieldNames.includes('name')\n const hasFirstName = fieldNames.includes('firstName')\n const hasLastName = fieldNames.includes('lastName')\n const hasEmail = fieldNames.includes('email')\n\n if (hasName) {\n return hasEmail ? \"data.name || data.email || 'Unknown'\" : \"data.name || 'Unknown'\"\n }\n if (hasFirstName && hasLastName) {\n const nameExpr = '`$' + '{data.firstName || \"\"} $' + '{data.lastName || \"\"}`.trim()'\n return hasEmail ? `(${nameExpr}) || data.email || 'Unknown'` : `(${nameExpr}) || 'Unknown'`\n }\n if (hasFirstName) {\n return hasEmail ? \"data.firstName || data.email || 'Unknown'\" : \"data.firstName || 'Unknown'\"\n }\n if (hasEmail) {\n return \"data.email || 'Unknown'\"\n }\n return \"'Unknown'\"\n}\n\n/**\n * Generate webhook code for a form\n * Handles custom payloads for specific forms (e.g., application form with price lookup)\n * Includes customFields expansion for forms with dynamicFields\n */\nfunction generateWebhookCode(\n formName: string,\n fields: FormField[],\n includeDynamicFields: boolean\n): string {\n // Application form has a custom payload with price lookup\n if (formName === 'application') {\n return `// Send webhook (fire-and-forget, non-blocking)\n // Custom payload for Zapier integration with price lookup\n ;(async () => {\n try {\n const settings = await getFormSettings('application')\n if (settings?.webhookEnabled && settings?.webhookUrl) {\n // Look up price from course tiers\n let price = ''\n if (data.course && data.bootcampTier) {\n const { courses } = await getCourses({ title: data.course })\n if (courses[0]) {\n const tier = courses[0].tiers?.find((t) => t.name === data.bootcampTier)\n if (tier) {\n const feeStr =\n data.preferredPaymentSchedule === 'monthly' ? tier.monthlyFee : tier.upfrontFee\n price = feeStr?.replace(/[$,]/g, '') || ''\n }\n }\n }\n\n // Expand customFields into individual webhook fields\n const customFieldsExpanded: Record<string, unknown> = {}\n if (data.customFields && typeof data.customFields === 'object') {\n for (const [key, value] of Object.entries(data.customFields)) {\n customFieldsExpanded[key] = value ?? ''\n }\n }\n\n sendWebhook(settings.webhookUrl, {\n bootcamp: data.course ?? '',\n first_name: data.firstName ?? '',\n last_name: data.lastName ?? '',\n email: data.email ?? '',\n linkedin_url: data.linkedin ?? '',\n employment_history: data.employmentHistory ?? '',\n education_history: data.isSelfTaught ?? '',\n why_take_this_bootcamp: data.whyDoYouWantToEnroll ?? '',\n price,\n payment_method: data.preferredPaymentMethod ?? '',\n marketing_source: data.howDidYouHearAboutUs ?? '',\n ...customFieldsExpanded\n })\n }\n } catch (error) {\n console.error('Failed to send webhook:', error)\n }\n })()`\n }\n\n // Default webhook payload for other forms\n const fieldMappings = fields\n .map((f) => `${toSnakeCase(f.name!)}: data.${f.name} ?? ''`)\n .join(',\\n ')\n\n // Add customFields expansion if form has dynamic fields\n const customFieldsCode = includeDynamicFields\n ? `\n // Expand customFields into individual webhook fields\n const customFieldsExpanded: Record<string, unknown> = {}\n if (data.customFields && typeof data.customFields === 'object') {\n for (const [key, value] of Object.entries(data.customFields)) {\n customFieldsExpanded[key] = value ?? ''\n }\n }\n`\n : ''\n\n const customFieldsSpread = includeDynamicFields ? ',\\n ...customFieldsExpanded' : ''\n\n return `// Send webhook (fire-and-forget, non-blocking)\n ;(async () => {\n try {\n const settings = await getFormSettings('${formName}')\n if (settings?.webhookEnabled && settings?.webhookUrl) {${customFieldsCode}\n sendWebhook(settings.webhookUrl, {\n form_name: '${formName}',\n submission_id: submission.id,\n submitted_at: submission.submittedAt,\n ${fieldMappings}${customFieldsSpread}\n })\n }\n } catch (error) {\n console.error('Failed to send webhook:', error)\n }\n })()`\n}\n\n/**\n * Generate Mailchimp audience subscription code for a form\n * Auto-detects the email field unless explicitly specified in schema\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 `// Add to Mailchimp audience (fire-and-forget, non-blocking)\n addToMailchimpAudience(data.${emailFieldName})`\n}\n\n/**\n * Check if schema is multi-step\n */\nfunction _isMultiStep(schema: FormSchema): boolean {\n return !!schema.steps && schema.steps.length > 0\n}\n\n/**\n * Map form field type to Drizzle type\n */\nfunction getDrizzleTypeForFormField(field: FormField, requiredImports: Set<string>): string {\n switch (field.type) {\n case 'text':\n if (field.maxLength) {\n requiredImports.add('varchar')\n return `varchar({ length: ${field.maxLength} })`\n }\n requiredImports.add('varchar')\n return 'varchar({ length: 255 })'\n case 'textarea':\n requiredImports.add('text')\n return 'text()'\n case 'email':\n requiredImports.add('varchar')\n return 'varchar({ length: 255 })'\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: 255 })'\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 // Check if list has nested fields (object array) or simple strings\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/**\n * Map form field type to Zod validation\n * @param field - The form field definition\n * @param options - Options for generating the zod type\n * @param options.treatAsOptional - If true, generate optional schema even if field.required is true\n * This is used for conditional required fields which are validated in superRefine\n */\nfunction getZodTypeForFormField(\n field: FormField,\n options: { treatAsOptional?: boolean } = {}\n): string {\n const label = field.label\n // For conditional required fields, treat as optional in base schema\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 if (field.maxLength)\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\n if (field.pattern)\n zodType += `.regex(new RegExp('${field.pattern}'), 'Invalid ${label} format')`\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 if (field.maxLength)\n zodType += `.max(${field.maxLength}, '${label} must be at most ${field.maxLength} characters')`\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 if (field.max !== undefined)\n zodType += `.max(${field.max}, '${label} must be at most ${field.max}')`\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 'timezone':\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} must be accepted' })`\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 'group':\n // Group fields are nested objects with sub-fields\n if (field.fields && field.fields.length > 0) {\n const nestedFields = field.fields\n .map((f) => ` ${f.name}: ${getZodTypeForFormField(f)}`)\n .join(',\\n')\n return isRequired\n ? `z.object({\\n${nestedFields}\\n })`\n : `z.object({\\n${nestedFields}\\n }).optional()`\n }\n return 'z.record(z.unknown()).optional()'\n case 'list':\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n // Generate object schema for nested fields\n const nestedFields = field.fields\n .map((f) => ` ${f.name}: ${getZodTypeForFormField(f)}`)\n .join(',\\n')\n return isRequired\n ? `z.array(z.object({\\n${nestedFields}\\n })).min(1, '${label} is required')`\n : `z.array(z.object({\\n${nestedFields}\\n })).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\n ? `z.string().min(1, 'Please upload a file for ${label}')`\n : 'z.string().transform(val => val === \"\" ? undefined : val).optional()'\n default:\n return isRequired ? `z.string().min(1, '${label} is required')` : 'z.string().optional()'\n }\n}\n\n/**\n * Generate database schema for form submissions\n */\nexport async function generateFormDatabase(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const tableName = `${toCamelCase(schema.name)}Submissions`\n const fields = getAllFields(schema)\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Track required Drizzle imports\n const requiredImports = new Set<string>(['serial', 'timestamp', 'text'])\n\n // Add jsonb import if form has dynamic fields\n if (includeDynamicFields) {\n requiredImports.add('jsonb')\n }\n\n // Generate field definitions\n const fieldDefinitions = fields\n .map((field) => {\n const drizzleType = getDrizzleTypeForFormField(field, requiredImports)\n const nullable = field.required ? '' : ''\n return ` ${field.name}: ${drizzleType}${nullable},`\n })\n .join('\\n')\n\n // Add customFields column if form has dynamic fields\n const customFieldsColumn = includeDynamicFields\n ? '\\n customFields: jsonb().$type<Record<string, unknown>>(),'\n : ''\n\n // Generate the table schema\n const tableSchema = `\nexport const ${tableName} = pgTable('${toPascalCase(schema.name)}Submissions', {\n id: serial().primaryKey().notNull(),\n${fieldDefinitions}${customFieldsColumn}\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 // Read existing schema file\n const schemaPath = path.join(paths.database, 'src/schema.ts')\n let schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n\n // Add required imports if not present\n const importLine = Array.from(requiredImports).sort().join(', ')\n if (!schemaContent.includes(`import { ${importLine}`)) {\n // Update the imports\n const drizzleImportRegex = /import\\s+{([^}]+)}\\s+from\\s+'drizzle-orm\\/pg-core'/\n const match = schemaContent.match(drizzleImportRegex)\n if (match) {\n const existingImports = match[1].split(',').map((i) => i.trim())\n const allImports = Array.from(new Set([...existingImports, ...Array.from(requiredImports)]))\n .sort()\n .join(', ')\n schemaContent = schemaContent.replace(\n drizzleImportRegex,\n `import { ${allImports} } from 'drizzle-orm/pg-core'`\n )\n }\n }\n\n // Check if table already exists\n if (schemaContent.includes(`export const ${tableName}`)) {\n if (!options.force) {\n console.warn(`⚠️ Table ${tableName} already exists. Use --force to overwrite.`)\n return schemaPath\n }\n // Remove existing table definition - match the full table definition including closing parenthesis\n const tableRegex = new RegExp(\n `export const ${tableName} = pgTable\\\\([\\\\s\\\\S]*?\\\\n\\\\}\\\\)\\\\n`,\n 'g'\n )\n schemaContent = schemaContent.replace(tableRegex, '')\n console.log(` ℹ️ Removed existing ${tableName} table definition`)\n }\n\n // Append new table schema\n schemaContent += `\\n${tableSchema}`\n\n // Write updated schema\n fs.writeFileSync(schemaPath, schemaContent, 'utf-8')\n\n console.log(` ✓ Database schema updated: ${schemaPath}`)\n return schemaPath\n}\n\n/**\n * Generate server actions for form submissions\n */\nexport async function generateFormActions(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const tableName = `${toCamelCase(formName)}Submissions`\n const pascalName = toPascalCase(formName)\n const fields = getAllFields(schema)\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Generate TypeScript interface for submission data\n // Conditional required fields are treated as optional (they may not be present when condition is not met)\n const dataInterfaceFields = fields\n .map((field) => {\n let tsType: string\n if (field.type === 'number') {\n tsType = 'number'\n } else if (field.type === 'checkbox') {\n tsType = 'boolean'\n } else if (field.type === 'multiselect') {\n tsType = 'string[]'\n } else if (field.type === 'list') {\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n tsType = 'Record<string, unknown>[]'\n } else {\n tsType = 'string[]'\n }\n } else {\n tsType = 'string'\n }\n // Conditional required fields are effectively optional\n const isEffectivelyRequired = field.required && !field.condition\n const optional = isEffectivelyRequired ? '' : ' | null'\n return ` ${field.name}${isEffectivelyRequired ? '' : '?'}: ${tsType}${optional}`\n })\n .join('\\n')\n\n // Add customFields if form has dynamic fields\n const customFieldsLine = includeDynamicFields\n ? '\\n customFields?: Record<string, unknown> | null'\n : ''\n const dataInterface = dataInterfaceFields + customFieldsLine\n\n const actionContent = `'use server'\n\nimport { ${tableName}, db } from '${ir.database}'\nimport { desc, eq, or } from 'drizzle-orm'\n${schema.notificationEmail ? \"import { render } from '@react-email/components'\" : ''}\n${schema.notificationEmail ? \"import { Resend } from 'resend'\" : ''}\nimport { sendWebhook } from '../utils/webhook'\n${schema.mailchimp ? \"import { addToMailchimpAudience } from '../utils/mailchimp'\" : ''}\n${formName === 'application' ? \"import { getCourses } from './courses'\" : ''}\nimport { getFormSettings } from './form-settings'\n${schema.notificationEmail ? `import { ${pascalName}SubmissionEmail } from '@/emails/${formName}-submission'` : ''}\n\n${schema.notificationEmail ? `const resend = new Resend(process.env.RESEND_API_KEY)\\n` : ''}\nexport interface ${pascalName}SubmissionData {\n id: number\n${dataInterface}\n ipAddress: string | null\n userAgent: string | null\n submittedAt: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface ${pascalName}SubmissionsResponse {\n submissions: ${pascalName}SubmissionData[]\n total: number\n}\n\nexport interface Create${pascalName}SubmissionInput {\n${dataInterface}\n ipAddress?: string\n userAgent?: string\n}\n\nexport interface Update${pascalName}SubmissionInput {\n id: number\n${dataInterface}\n}\n\nexport interface Create${pascalName}SubmissionResult {\n success: boolean\n error?: string\n submission?: ${pascalName}SubmissionData\n}\n\nexport interface Delete${pascalName}SubmissionResult {\n success: boolean\n error?: string\n count?: number\n}\n\nexport async function get${pascalName}Submissions(): Promise<${pascalName}SubmissionsResponse> {\n try {\n const submissions = await db.select().from(${tableName}).orderBy(desc(${tableName}.submittedAt))\n const total = submissions.length\n\n return {\n submissions: submissions as ${pascalName}SubmissionData[],\n total\n }\n } catch (error) {\n console.error('Error fetching ${formName} submissions:', error)\n throw new Error('Failed to fetch ${formName} submissions')\n }\n}\n\nexport async function get${pascalName}Submission(id: number): Promise<${pascalName}SubmissionData | null> {\n try {\n const [submission] = await db\n .select()\n .from(${tableName})\n .where(eq(${tableName}.id, id))\n .limit(1)\n\n return submission as ${pascalName}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\nexport async function create${pascalName}Submission(\n data: Create${pascalName}SubmissionInput\n): Promise<Create${pascalName}SubmissionResult> {\n try {\n // Validate data (basic server-side validation)\n // Unconditional required fields\n ${fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) => `if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }`\n )\n .join('\\n ')}\n // Conditional required fields - only validate when condition is met\n ${fields\n .filter((f) => f.required && f.condition)\n .map((f) => {\n // Convert condition to use data. prefix for field references\n const serverCondition = f.condition!.replace(/(\\w+)\\s*(===|!==|==|!=)/g, 'data.$1 $2')\n return `if (${serverCondition}) {\n if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }\n }`\n })\n .join('\\n ')}\n\n // Save to database (MUST succeed for success response)\n const [submission] = await db\n .insert(${tableName})\n .values({\n ...data,\n submittedAt: new Date().toISOString()\n })\n .returning()\n\n ${\n schema.notificationEmail\n ? `// Send email notification (fire-and-forget pattern)\n // IMPORTANT: Email failures don't affect the response to client\n // If DB save succeeded, client gets success = true\n if (process.env.RESEND_API_KEY) {\n // Email sending wrapped in try-catch to prevent throwing\n try {\n // Get notification emails from form settings (primary), fall back to env var (backup)\n const settings = await getFormSettings('${formName}')\n const notificationEmails = settings?.notificationEmails\n ? settings.notificationEmails.split(',').map((e) => e.trim()).filter(Boolean)\n : process.env.NOTIFICATION_EMAIL\n ? [process.env.NOTIFICATION_EMAIL]\n : []\n\n if (notificationEmails.length === 0) {\n console.warn('No notification emails configured for ${formName} form')\n } else {\n // Render the React Email template\n const emailHtml = await render(\n ${pascalName}SubmissionEmail({\n ${generateEmailPropsForRender(fields, includeDynamicFields)}\n submittedAt: submission.submittedAt\n })\n )\n\n await resend.emails.send({\n from: process.env.FROM_EMAIL || 'noreply@betterstart.io',\n to: notificationEmails,\n subject: \\`New ${schema.label}: \\${${getEmailSubjectNameExpr(fields)}} (#\\${submission.id})\\`,\n html: emailHtml\n })\n }\n } catch (error) {\n // Log error but DON'T throw - submission already succeeded\n console.error('Failed to send notification email:', error)\n // Optionally: Store failed email in a queue for retry\n }\n }`\n : ''\n }\n\n ${generateWebhookCode(formName, fields, includeDynamicFields)}\n\n ${generateMailchimpCode(schema, fields)}\n\n return {\n success: true,\n submission: submission as ${pascalName}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\nexport async function update${pascalName}Submission(\n id: number,\n data: Create${pascalName}SubmissionInput | Update${pascalName}SubmissionInput\n): Promise<Create${pascalName}SubmissionResult> {\n try {\n // Validate data (basic server-side validation)\n // Unconditional required fields\n ${fields\n .filter((f) => f.required && !f.condition)\n .map(\n (f) => `if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }`\n )\n .join('\\n ')}\n // Conditional required fields - only validate when condition is met\n ${fields\n .filter((f) => f.required && f.condition)\n .map((f) => {\n // Convert condition to use data. prefix for field references\n const serverCondition = f.condition!.replace(/(\\w+)\\s*(===|!==|==|!=)/g, 'data.$1 $2')\n return `if (${serverCondition}) {\n if (!data.${f.name}) {\n return { success: false, error: '${f.label} is required' }\n }\n }`\n })\n .join('\\n ')}\n\n // Update in database\n const [submission] = await db\n .update(${tableName})\n .set({\n ...data,\n updatedAt: new Date().toISOString()\n })\n .where(eq(${tableName}.id, id))\n .returning()\n\n if (!submission) {\n return { success: false, error: 'Submission not found' }\n }\n\n return {\n success: true,\n submission: submission as ${pascalName}SubmissionData\n }\n } catch (error) {\n console.error(\\`Error updating ${formName} submission \\${id}:\\`, error)\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Failed to update ${formName} submission'\n }\n }\n}\n\nexport async function delete${pascalName}Submission(id: number): Promise<Delete${pascalName}SubmissionResult> {\n try {\n await db.delete(${tableName}).where(eq(${tableName}.id, id))\n\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\nexport async function deleteBulk${pascalName}Submissions(ids: number[]): Promise<Delete${pascalName}SubmissionResult> {\n try {\n if (ids.length === 0) {\n return { success: true, count: 0 }\n }\n\n await db.delete(${tableName}).where(\n or(...ids.map(id => eq(${tableName}.id, id)))\n )\n\n return { \n success: true,\n count: ids.length\n }\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// Export functions for CSV/JSON\nexport async function export${pascalName}SubmissionsCSV(): Promise<string> {\n const { submissions } = await get${pascalName}Submissions()\n \n if (submissions.length === 0) {\n return ''\n }\n\n // Generate CSV header\n const headers = Object.keys(submissions[0]).join(',')\n \n // Generate CSV rows\n const rows = submissions.map((sub) =>\n Object.values(sub)\n .map((val) => {\n if (val === null || val === undefined) return ''\n const str = String(val)\n // Escape quotes and wrap in quotes if contains comma, quote, or newline\n if (str.includes(',') || str.includes('\"') || str.includes('\\\\n')) {\n return \\`\"\\${str.replace(/\"/g, '\"\"')}\"\\`\n }\n return str\n })\n .join(',')\n )\n\n return [headers, ...rows].join('\\\\n')\n}\n\nexport async function export${pascalName}SubmissionsJSON(): Promise<string> {\n const { submissions } = await get${pascalName}Submissions()\n return JSON.stringify(submissions, null, 2)\n}\n`\n\n // Write actions file\n const actionsPath = path.join(paths.lib, 'src/actions', `${formName}-form.ts`)\n const actionsDir = path.dirname(actionsPath)\n ensureDir(actionsDir)\n\n if (fs.existsSync(actionsPath) && !options.force) {\n console.warn(`⚠️ Actions file already exists: ${actionsPath}. Use --force to overwrite.`)\n return actionsPath\n }\n\n fs.writeFileSync(actionsPath, actionContent, 'utf-8')\n console.log(` ✓ Actions generated: ${actionsPath}`)\n\n // Update index.ts to export new actions\n const indexPath = path.join(actionsDir, 'index.ts')\n const exportLine = `export * from './${formName}-form'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n console.log(` ✓ Updated actions/index.ts`)\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n console.log(` ✓ Created actions/index.ts`)\n }\n\n return actionsPath\n}\n\n/**\n * Generate React Query hook for form submissions\n */\nexport async function generateFormHook(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const camelName = toCamelCase(formName)\n\n const hookContent = `import {\n create${pascalName}Submission,\n delete${pascalName}Submission,\n export${pascalName}SubmissionsCSV,\n export${pascalName}SubmissionsJSON,\n get${pascalName}Submission,\n get${pascalName}Submissions,\n update${pascalName}Submission\n} from '${ir.actions(`${formName}-form`)}'\nimport type { Create${pascalName}SubmissionInput } from '${ir.actions(`${formName}-form`)}'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useRouter } from 'next/navigation'\nimport { toast } from 'sonner'\n\nexport function use${pascalName}Submissions(search?: string) {\n return useQuery({\n queryKey: ['${camelName}-submissions', search ?? ''],\n queryFn: () => get${pascalName}Submissions()\n })\n}\n\nexport function use${pascalName}Submission(id: number | null) {\n return useQuery({\n queryKey: ['${camelName}-submission', id],\n queryFn: () => get${pascalName}Submission(id!),\n enabled: !!id\n })\n}\n\nexport function useCreate${pascalName}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (data: Create${pascalName}SubmissionInput) => create${pascalName}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${(schema.successMessage || 'Form submitted successfully').replace(\n /'/g,\n \"\\\\'\"\n )}')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-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 useUpdate${pascalName}Submission() {\n const queryClient = useQueryClient()\n const router = useRouter()\n\n return useMutation({\n mutationFn: ({ id, data }: { id: number; data: Create${pascalName}SubmissionInput }) => update${pascalName}Submission(id, data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('Submission updated successfully')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submissions'] })\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submission'] })\n router.push('/admin/forms/${formName}')\n } else {\n toast.error(result.error || 'Failed to update submission')\n }\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to update submission')\n }\n })\n}\n\nexport function useDelete${pascalName}Submission() {\n const queryClient = useQueryClient()\n\n return useMutation({\n mutationFn: (id: number) => delete${pascalName}Submission(id),\n onSuccess: async () => {\n toast.success('Submission deleted successfully')\n await queryClient.refetchQueries({ queryKey: ['${camelName}-submissions'] })\n },\n onError: (error: Error) => {\n toast.error(error.message || 'Failed to delete submission')\n }\n })\n}\n\nexport function useExport${pascalName}SubmissionsCSV() {\n return useMutation({\n mutationFn: export${pascalName}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${pascalName}SubmissionsJSON() {\n return useMutation({\n mutationFn: export${pascalName}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 const hookPath = path.join(paths.hooks, 'src', `use-${formName}-form.ts`)\n const hooksDir = path.dirname(hookPath)\n ensureDir(hooksDir)\n\n if (fs.existsSync(hookPath) && !options.force) {\n console.warn(`⚠️ Hook already exists: ${hookPath}. Use --force to overwrite.`)\n return hookPath\n }\n\n fs.writeFileSync(hookPath, hookContent, 'utf-8')\n console.log(` ✓ Hook generated: ${hookPath}`)\n\n // Update index.ts to export new hook\n const indexPath = path.join(hooksDir, 'index.ts')\n const exportLine = `export * from './use-${formName}-form'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n console.log(` ✓ Updated hooks/index.ts`)\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n console.log(` ✓ Created hooks/index.ts`)\n }\n\n return hookPath\n}\n\n/**\n * Generate form field JSX\n */\nfunction generateFormFieldJSX(\n field: FormField,\n options: { useCourseColors?: boolean } = {}\n): string {\n const fieldName = field.name || ''\n const label = field.label\n const placeholder = field.placeholder || ''\n const hint = field.hint || ''\n const { useCourseColors = false } = options\n\n // Handle hidden fields - they don't render but are in the form\n if (field.hidden) {\n return ` <input type=\"hidden\" {...form.register(\"${fieldName}\")} />`\n }\n\n // Extract field dependencies from condition (e.g., \"appliedBefore === 'no'\" -> [\"appliedBefore\"])\n const getWatchFields = (condition?: string): string[] => {\n if (!condition) return []\n const fieldNamePattern = /\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g\n const matches = condition.matchAll(fieldNamePattern)\n const fields = Array.from(matches, (m) => m[1]).filter(\n (f) => !['true', 'false', 'null', 'undefined'].includes(f)\n )\n return [...new Set(fields)] // Remove duplicates\n }\n\n // Generate the actual field JSX (inner content)\n const generateFieldContent = (): string => {\n // Handle relationship fields (dynamic options from database)\n if (field.relationship && field.relationshipField && field.nuqsQueryParam) {\n const relationshipField = field.relationshipField\n\n // Generate options variable name (e.g., tierOptions)\n const optionsVarName = `${relationshipField}Options`\n\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"space-y-2\">\n <FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n ${\n hint\n ? `<FormDescription dangerouslySetInnerHTML={{ __html: renderMarkdownInline(\"${hint.replace(\n /\"/g,\n '\\\\\"'\n )}\") }} />`\n : ''\n }\n <FormControl>\n {${optionsVarName}.length > 0 ? (\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n {${optionsVarName}.map((option) => (\n <div \n key={option.value} \n className=\"flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5\" \n data-state={field.value === option.value ? \"checked\" : \"unchecked\"}\n style={{\n borderColor: field.value === option.value \n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)',\n backgroundColor: field.value === option.value\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem \n value={option.value} \n id={\\`${fieldName}-\\${option.value}\\`}\n style={{\n borderColor: field.value === option.value \n ? courseColor\n : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor={\\`${fieldName}-\\${option.value}\\`}>{option.label}</Label>\n </div>\n ))}\n </RadioGroup>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n Please select a course first\n </p>\n )}\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n }\n\n // Handle group type - render nested fields in a grid\n if (field.type === 'group' && field.fields) {\n const columns = field.columns || 1\n const gridClass = columns > 1 ? `grid-cols-${columns}` : 'grid-cols-1'\n const groupFields = field.fields\n .map((nestedField) => generateFormFieldJSX(nestedField, options))\n .join('\\n\\n')\n\n // Only show heading if label is set\n const headingJSX = label\n ? ` <h3 className=\"text-lg font-medium\">${label}</h3>`\n : ''\n\n // Generate the group content\n const groupContent = ` <div className=\"space-y-8\">\n${headingJSX}\n <div className=\"grid ${gridClass} gap-8\">\n${groupFields}\n </div>\n </div>`\n\n // Check for group-level showWhen condition\n if (field.showWhen) {\n const showWhenCondition = showWhenToCondition(field.showWhen)\n const watchFields = getWatchFields(showWhenCondition)\n\n // Split condition by string literals to avoid replacing inside them\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = showWhenCondition\n let match: RegExpExecArray | null\n\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n // Replace field names with watched variable names (e.g., fieldName -> fieldNameValue)\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (m) => {\n if (['true', 'false', 'null', 'undefined'].includes(m)) {\n return m\n }\n if (watchFields.includes(m)) {\n return `${m}Value`\n }\n return m\n })\n })\n\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` {${conditionCheck} && (\n${groupContent}\n )}`\n }\n\n return groupContent\n }\n\n switch (field.type) {\n case 'textarea':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Textarea placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'email':\n case 'phone':\n case 'url':\n case 'text':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input type=\"${\n field.type === 'email'\n ? 'email'\n : field.type === 'phone'\n ? 'tel'\n : field.type === 'url'\n ? 'url'\n : 'text'\n }\" placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'number':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input type=\"number\" placeholder=\"${placeholder}\" {...field} onChange={(e) => field.onChange(e.target.valueAsNumber)} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'date':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input\n type=\"date\"\n {...field}\n value={field.value || ''}\n />\n </FormControl>\n \n </FormItem>\n )}\n />`\n\n case 'checkbox':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value}\n onCheckedChange={field.onChange}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel${hint ? ' className=\"leading-snug\"' : ''}>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n ${\n hint\n ? `<FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />`\n : ''\n }\n </div>\n \n </FormItem>\n )}\n />`\n\n case 'select':\n if (!field.options || field.options.length === 0) {\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <Input placeholder=\"${placeholder}\" {...field} value={field.value || ''} />\n </FormControl>\n \n </FormItem>\n )}\n />`\n }\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field, fieldState }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n \n <FormControl>\n <Select onValueChange={field.onChange} value={field.value}>\n <SelectTrigger aria-invalid={fieldState.error ? \"true\" : \"false\"}>\n <SelectValue placeholder=\"${placeholder || 'Please select'}\" />\n </SelectTrigger>\n <SelectContent>\n ${field.options\n .map(\n (opt) => `<SelectItem value=\"${opt.value}\">${opt.label}</SelectItem>`\n )\n .join('\\n ')}\n </SelectContent>\n </Select>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'radio':\n if (!field.options || field.options.length === 0) {\n return ` <div>Radio field requires options</div>`\n }\n\n // Use course colors only for application form\n if (useCourseColors) {\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"${hint ? 'space-y-3' : 'space-y-2'}\">\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n\n <FormControl>\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n ${field.options\n .map(\n (opt) => `<div \n className=\"flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5\" \n data-state={field.value === \"${opt.value}\" ? \"checked\" : \"unchecked\"}\n style={{\n borderColor: field.value === \"${opt.value}\"\n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)',\n backgroundColor: field.value === \"${opt.value}\"\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem \n value=\"${opt.value}\" \n id=\"${fieldName}-${opt.value}\"\n style={{\n borderColor: field.value === \"${opt.value}\"\n ? courseColor\n : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor=\"${fieldName}-${opt.value}\">${opt.label}</Label>\n </div>`\n )\n .join('\\n ')}\n </RadioGroup>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n }\n\n // Standard styling for other forms\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem className=\"${hint ? 'space-y-3' : 'space-y-2'}\">\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <RadioGroup onValueChange={field.onChange} value={field.value || ''}>\n ${field.options\n .map(\n (opt) => `<div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"${opt.value}\" id=\"${fieldName}-${opt.value}\" />\n <Label htmlFor=\"${fieldName}-${opt.value}\">${opt.label}</Label>\n </div>`\n )\n .join('\\n ')}\n </RadioGroup>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'multiselect':\n // TODO: Implement proper multiselect component\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <div>Multi-select field (to be implemented)</div>\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'timezone':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <TimezoneSelect \n value={field.value || ''} \n onValueChange={field.onChange}\n placeholder=\"${placeholder || 'Select a timezone'}\"\n />\n </FormControl>\n \n \n </FormItem>\n )}\n />`\n\n case 'list':\n // Check if list has nested fields (object array) or simple strings\n if (field.fields && field.fields.length > 0) {\n // Generate nested fields configuration for DynamicObjectListField\n const nestedFieldsConfig = field.fields\n .map((f) => {\n const config: string[] = [\n `name: '${f.name}'`,\n `type: '${f.type}'`,\n `label: '${f.label}'`\n ]\n if (f.required) config.push('required: true')\n if (f.placeholder) config.push(`placeholder: '${f.placeholder}'`)\n if (f.options && f.options.length > 0) {\n const opts = f.options\n .map((opt) => `{ label: '${opt.label}', value: '${opt.value}' }`)\n .join(', ')\n config.push(`options: [${opts}]`)\n }\n return `{ ${config.join(', ')} }`\n })\n .join(',\\n ')\n\n return ` <DynamicObjectListField\n name=\"${fieldName}\"\n label=\"${label}\"\n fields={[\n ${nestedFieldsConfig}\n ]}${field.columns ? `\\n columns={${field.columns}}` : ''}\n />`\n }\n\n return ` <DynamicListField\n name=\"${fieldName}\"\n label=\"${label}\"\n placeholder=\"${placeholder || 'Enter value'}\"\n />`\n\n case 'file':\n case 'upload':\n return ` <FormField\n control={form.control}\n name=\"${fieldName}\"\n render={({ field }) => (\n <FormItem${hint ? ' className=\"space-y-3\"' : ''}>\n ${\n hint\n ? `<div className=\"flex flex-col gap-1\">\n <FormLabel className=\"leading-snug\">${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>\n\n <FormDescription\n className=\"text-sm\"\n dangerouslySetInnerHTML={{\n __html: renderMarkdownInline(\n \"${hint.replace(/\"/g, '\\\\\"')}\"\n ),\n }}\n />\n </div>`\n : `<FormLabel>${label}${\n field.required ? ' <span className=\"text-red-500\">*</span>' : ''\n }</FormLabel>`\n }\n <FormControl>\n <FileUploadField\n value={field.value || ''}\n onChange={field.onChange}\n onBlur={field.onBlur}\n accept=\"${field.accept || '*/*'}\"\n maxSizeInMB={${field.maxFileSize || 100}}\n />\n </FormControl>\n\n\n </FormItem>\n )}\n />`\n\n case 'dynamicFields':\n // Render dynamic fields from course.applicationFields inline\n // Uses dynamicFieldErrors state for error handling since these fields aren't in the Zod schema\n return ` {/* Dynamic fields from CMS */}\n {selectedCourse?.applicationFields?.map((dynamicField, index) => {\n const fieldName = dynamicField.name || \\`dynamicField_\\${index}\\`\n const errorMessage = dynamicFieldErrors[fieldName]\n const hasError = !!errorMessage\n\n // Check showWhen condition - hide field if condition not met\n if (!isFieldVisible(dynamicField)) {\n return null\n }\n\n // Render based on field type\n switch (dynamicField.type) {\n case 'textarea':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Textarea\n id={fieldName}\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues)}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'select':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Controller\n name={fieldName as keyof FormValues}\n control={form.control}\n render={({ field: selectField }) => (\n <Select\n value={(selectField.value as string) || ''}\n onValueChange={selectField.onChange}\n >\n <SelectTrigger id={fieldName} aria-invalid={hasError} className={hasError ? 'border-destructive' : ''}>\n <SelectValue placeholder={dynamicField.placeholder || 'Select an option'} />\n </SelectTrigger>\n <SelectContent>\n {dynamicField.options?.map((option) => (\n <SelectItem key={option.value} value={option.value || ''}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'radio':\n return (\n <div key={fieldName} className=\"space-y-3\">\n <Label className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <RadioGroup\n onValueChange={(value) => form.setValue(fieldName as keyof FormValues, value as FormValues[keyof FormValues])}\n defaultValue={form.getValues(fieldName as keyof FormValues) as string}\n >\n {dynamicField.options?.map((option) => (\n <div\n key={option.value}\n className={\\`flex items-center space-x-2 hover:cursor-pointer border rounded-md corner-squircle py-2 pl-3 pr-5 \\${hasError ? 'border-destructive' : ''}\\`}\n data-state={form.watch(fieldName as keyof FormValues) === option.value ? 'checked' : 'unchecked'}\n style={{\n borderColor: hasError ? undefined : (form.watch(fieldName as keyof FormValues) === option.value\n ? \\`light-dark(\\${radioBorderColorLight}, \\${radioBorderColorDark})\\`\n : 'var(--border)'),\n backgroundColor: form.watch(fieldName as keyof FormValues) === option.value\n ? \\`light-dark(\\${radioBgColorLight}, \\${radioBgColorDark})\\`\n : 'transparent'\n } as React.CSSProperties}\n >\n <RadioGroupItem\n value={option.value || ''}\n id={\\`\\${fieldName}-\\${option.value}\\`}\n style={{\n borderColor: form.watch(fieldName as keyof FormValues) === option.value ? courseColor : undefined\n } as React.CSSProperties}\n />\n <Label htmlFor={\\`\\${fieldName}-\\${option.value}\\`}>{option.label}</Label>\n </div>\n ))}\n </RadioGroup>\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'checkbox':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={fieldName}\n {...form.register(fieldName as keyof FormValues)}\n aria-invalid={hasError}\n className={\\`h-4 w-4 rounded border-gray-300 \\${hasError ? 'border-destructive' : ''}\\`}\n />\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n </div>\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n case 'number':\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Input\n id={fieldName}\n type=\"number\"\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues, { valueAsNumber: true })}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n default:\n // Default to text input\n return (\n <div key={fieldName} className=\"grid gap-3\">\n <Label htmlFor={fieldName} className={hasError ? 'text-destructive' : ''}>\n {dynamicField.label}\n {dynamicField.required && <span className=\"text-red-500 ml-1\">*</span>}\n </Label>\n <Input\n id={fieldName}\n placeholder={dynamicField.placeholder || ''}\n aria-invalid={hasError}\n className={hasError ? 'border-destructive' : ''}\n {...form.register(fieldName as keyof FormValues)}\n />\n {dynamicField.hint && !hasError && (\n <p className=\"text-sm text-muted-foreground\">{dynamicField.hint}</p>\n )}\n {hasError && (\n <p className=\"text-destructive text-sm\">{errorMessage}</p>\n )}\n </div>\n )\n }\n })}`\n\n default:\n return ` <div>Unknown field type: ${field.type}</div>`\n }\n }\n\n // Generate the field content\n const fieldContent = generateFieldContent()\n\n // Wrap with conditional rendering if condition is specified\n if (field.condition) {\n const watchFields = getWatchFields(field.condition)\n\n // Split condition by string literals to avoid replacing inside them\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = field.condition\n let match: RegExpExecArray | null\n\n // Extract string literals\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n // Replace field names with watched variable names for proper reactivity\n // Using useWatch hook at the top of the component ensures React re-renders\n // when the watched value changes, unlike inline form.watch() which may not trigger re-renders\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (m) => {\n // Don't replace JavaScript keywords\n if (['true', 'false', 'null', 'undefined'].includes(m)) {\n return m\n }\n // Replace field names with watched variable names (e.g., fieldName -> fieldNameValue)\n if (watchFields.includes(m)) {\n return `${m}Value`\n }\n return m\n })\n })\n\n // Reconstruct the condition\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` {${conditionCheck} && (\n${fieldContent}\n )}`\n }\n\n return fieldContent\n}\n\n// Will continue with form component generation...\n\n/**\n * Generate public form component (supports both single-step and multi-step)\n */\nexport async function generateFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n if (schema.steps && schema.steps.length > 0) {\n return generateMultiStepFormComponent(schema, options)\n }\n return generateSingleStepFormComponent(schema, options)\n}\n\n/**\n * Generate single-step form component\n */\nasync function generateSingleStepFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n\n // Get flattened fields for schema/validation (no groups)\n const fields = getAllFields(schema)\n\n // Get actual form fields (used for rendering, includes groups)\n const formFields = schema.fields || []\n\n // Determine required imports based on field types\n const hasSelect = fields.some((f) => f.type === 'select')\n const hasCheckbox = fields.some((f) => f.type === 'checkbox')\n const hasRadio = fields.some((f) => f.type === 'radio')\n const hasTextarea = fields.some((f) => f.type === 'textarea')\n const hasTimezone = fields.some((f) => f.type === 'timezone')\n const hasList = fields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n const hasObjectList = fields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)\n const hasUpload = fields.some((f) => f.type === 'upload' || f.type === 'file')\n const hasHints = fields.some((f) => f.hint)\n const hasRelationshipFields = fields.some(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n // Fields that capture URL query parameters\n const urlParamFields = fields.filter((f) => f.urlParam)\n const hasUrlParamFields = urlParamFields.length > 0\n\n // Get relationship field details\n const relationshipField = fields.find(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n const relationshipHook = relationshipField?.relationship === 'courses' ? 'useCourseBySlug' : null\n\n // Check if there's a hidden course field that should get its value from selectedCourse\n const hasHiddenCourseField =\n relationshipField?.relationship === 'courses' &&\n fields.some((f) => f.name === 'course' && f.hidden)\n\n // Check if schema has conditional fields\n const hasConditionalFields = fields.some((f) => f.condition)\n\n // Collect conditional fields for refinement\n const conditionalFields = fields.filter((f) => f.condition && f.required)\n\n // Collect all unique fields that need to be watched for showWhen conditions\n const collectWatchedFields = (formFieldList: FormField[]): string[] => {\n const watchedFields = new Set<string>()\n const collectFromField = (f: FormField) => {\n if (f.showWhen?.field) {\n watchedFields.add(f.showWhen.field)\n }\n if (f.type === 'group' && f.fields) {\n f.fields.forEach(collectFromField)\n }\n }\n formFieldList.forEach(collectFromField)\n return Array.from(watchedFields)\n }\n const watchedFieldNames = collectWatchedFields(formFields)\n const hasWatchedFields = watchedFieldNames.length > 0\n\n // Check if schema has dynamic fields\n const includeDynamicFields = hasDynamicFields(schema)\n\n // Generate Zod schema (flattened, no groups)\n // Make conditional required fields optional in base schema\n // Also make hidden course field optional (value injected at submit time)\n const zodFields = fields\n .filter((f) => f.name)\n .map((f) => {\n // If field has a condition and is required, treat as optional in base schema\n // The requirement will be validated in superRefine when condition is met\n // Also treat hidden course field as optional since value is injected at submit time\n const treatAsOptional =\n !!(f.condition && f.required) || (hasHiddenCourseField && f.name === 'course' && f.hidden)\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n\n // Generate form fields JSX (includes groups)\n // Only use course colors for the 'application' form\n const useCourseColors = formName === 'application'\n const formFieldsJSX = formFields\n .map((f) => generateFormFieldJSX(f, { useCourseColors }))\n .join('\\n\\n')\n\n // Generate default values (flattened, no groups)\n const defaultValues = fields\n .filter((f) => f.name) // Filter out group fields\n .map((f) => {\n let defaultVal: string\n if (f.defaultValue !== undefined) {\n defaultVal = JSON.stringify(f.defaultValue)\n } else if (f.type === 'checkbox') {\n defaultVal = 'false'\n } else if (f.type === 'number') {\n defaultVal = '0'\n } else if (f.type === 'multiselect' || f.type === 'list') {\n defaultVal = '[]'\n } else if (f.type === 'select') {\n // Select fields default to undefined so placeholder shows\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && !f.required) {\n // Optional radio fields default to undefined\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && f.required && f.options && f.options.length > 0) {\n // Required radio fields default to first option value (radios don't have placeholder)\n defaultVal = `'${f.options[0].value}'`\n } else {\n defaultVal = \"''\"\n }\n return ` ${f.name}: ${defaultVal}`\n })\n .join(',\\n')\n\n const formContent = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport {\n Button,${hasCheckbox ? '\\n Checkbox,' : ''}${\n hasList ? '\\n DynamicListField,' : ''\n }${hasObjectList ? '\\n DynamicObjectListField,' : ''}${hasUpload ? '\\n FileUploadField,' : ''}\n Form,\n FormControl,${hasHints ? '\\n FormDescription,' : ''}\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,${hasRadio || includeDynamicFields ? '\\n Label,\\n RadioGroup,\\n RadioGroupItem,' : ''}${\n hasSelect || includeDynamicFields\n ? '\\n Select,\\n SelectContent,\\n SelectItem,\\n SelectTrigger,\\n SelectValue,'\n : ''\n }${hasTextarea ? '\\n Textarea,' : ''}${hasTimezone ? '\\n TimezoneSelect' : ''}\n} from '${ir.webUi}'\n${relationshipHook ? `import { ${relationshipHook} } from '${ir.hooks}'` : ''}\nimport type { Create${pascalName}SubmissionInput } from '${ir.actions(`${formName}-form`)}'\nimport { create${pascalName}Submission } from '${ir.actions(`${formName}-form`)}'${\n hasHints ? `\\nimport { renderMarkdownInline } from '${ir.lib}'` : ''\n }${hasRelationshipFields && relationshipHook ? `\\nimport { hexToOklab } from '${ir.utils}'` : ''}\nimport { useMutation } from '@tanstack/react-query'${\n hasRelationshipFields || hasUrlParamFields ? `\\nimport { useQueryState } from 'nuqs'` : ''\n }${hasRelationshipFields || hasUrlParamFields ? `\\nimport React from 'react'` : ''}\nimport { ${includeDynamicFields ? 'Controller, ' : ''}useForm${hasWatchedFields ? ', useWatch' : ''} } from 'react-hook-form'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\n\nconst formSchema = z.object({\n${zodFields}\n})${\n hasConditionalFields\n ? `.superRefine((data, ctx) => {\n${conditionalFields\n .map((f) => {\n const condition = f.condition || ''\n const zodType = getZodTypeForFormField(f)\n const errorMessage = zodType.match(/message: '([^']+)'/)?.[1] || `${f.label} is required`\n\n // Transform condition to use data instead of formValues\n const parts: string[] = []\n const stringLiterals: string[] = []\n let remaining = condition\n let match: RegExpExecArray | null\n\n const stringRegex = /(['\"])(?:\\\\.|(?!\\1)[^\\\\])*\\1/g\n match = stringRegex.exec(remaining)\n while (match !== null) {\n parts.push(remaining.slice(0, match.index))\n stringLiterals.push(match[0])\n remaining = remaining.slice(match.index + match[0].length)\n match = stringRegex.exec(remaining)\n }\n parts.push(remaining)\n\n const processedParts = parts.map((part) => {\n return part.replace(/\\b([a-zA-Z_$][a-zA-Z0-9_$]*)\\b/g, (match) => {\n if (['true', 'false', 'null', 'undefined'].includes(match)) {\n return match\n }\n if (fields.find((field) => field.name === match)) {\n return `data.${match}`\n }\n return match\n })\n })\n\n let conditionCheck = ''\n for (let i = 0; i < processedParts.length; i++) {\n conditionCheck += processedParts[i]\n if (i < stringLiterals.length) {\n conditionCheck += stringLiterals[i]\n }\n }\n\n return ` // Validate ${f.name} when condition is met\n if (${conditionCheck}) {\n if (!data.${f.name}) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: '${errorMessage}',\n path: ['${f.name}']\n })\n }\n }`\n })\n .join('\\n')}\n})`\n : ''\n }\n\ntype FormValues = z.infer<typeof formSchema>\n\nexport function ${pascalName}Form() {${\n hasUrlParamFields\n ? `\n // Query state for URL parameters\n${urlParamFields.map((f) => ` const [${f.urlParam}Param] = useQueryState('${f.urlParam}')`).join('\\n')}`\n : ''\n }${\n hasRelationshipFields\n ? `\n // Query state for relationship fields\n const [courseSlug] = useQueryState('course')\n ${relationshipHook ? `const { data: selectedCourse } = ${relationshipHook}(courseSlug)` : ''}`\n : ''\n }${\n hasRelationshipFields && relationshipHook\n ? `\n\n // Generate course color variants for radio groups\n const courseColor = selectedCourse?.color ?? '#000000'\n const radioBorderColorLight = hexToOklab(courseColor, 0.3)\n const radioBorderColorDark = hexToOklab(courseColor, 0.4)\n const radioBgColorLight = hexToOklab(courseColor, 0.1)\n const radioBgColorDark = hexToOklab(courseColor, 0.1)`\n : ''\n }\n\n const createMutation = useMutation({\n mutationFn: (data: Create${pascalName}SubmissionInput) => create${pascalName}Submission(data),\n onSuccess: async (result) => {\n if (result.success) {\n toast.success('${(\n schema.successMessage || `${schema.label} submitted successfully`\n ).replace(/'/g, \"\\\\'\")}')\n form.reset()\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 const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n${defaultValues}\n }\n })${\n hasWatchedFields\n ? `\n\n // Watch fields for conditional rendering\n${watchedFieldNames.map((fieldName) => ` const ${fieldName}Value = useWatch({ control: form.control, name: '${fieldName}' })`).join('\\n')}`\n : ''\n }${\n hasRelationshipFields && relationshipField\n ? `\n\n // Generate tier options from selected course\n const ${relationshipField.relationshipField}Options = React.useMemo(() => {\n if (!selectedCourse?.${relationshipField.relationshipField}) return []\n return selectedCourse.${relationshipField.relationshipField}.map((tier) => ({\n value: tier.name || '',\n label: \\`\\${tier.name} - \\${tier.upfrontFee} upfront / \\${tier.monthlyFee} monthly\\`\n }))\n }, [selectedCourse])\n\n // Auto-select first tier option when tiers load or course changes\n React.useEffect(() => {\n if (${relationshipField.relationshipField}Options.length > 0) {\n const currentValue = form.getValues('${relationshipField.name}')\n const isValidOption = ${relationshipField.relationshipField}Options.some(opt => opt.value === currentValue)\n if (!currentValue || !isValidOption) {\n form.setValue('${relationshipField.name}', ${relationshipField.relationshipField}Options[0].value)\n }\n }\n }, [${relationshipField.relationshipField}Options, form])`\n : ''\n }${\n hasUrlParamFields\n ? `\n\n // Sync hidden fields with URL query parameters\n React.useEffect(() => {\n${urlParamFields\n .map(\n (f) => ` if (${f.urlParam}Param) {\n form.setValue('${f.name}', ${f.urlParam}Param)\n }`\n )\n .join('\\n')}\n }, [${urlParamFields.map((f) => `${f.urlParam}Param`).join(', ')}, form])`\n : ''\n }\n\n${\n includeDynamicFields\n ? `\n // Track dynamic field errors separately (form.setError doesn't trigger re-renders for dynamic fields)\n const [dynamicFieldErrors, setDynamicFieldErrors] = React.useState<Record<string, string>>({})\n\n // Watch all dynamic fields that are used in showWhen conditions to trigger re-renders\n const watchedDynamicFields = React.useMemo(() => {\n const fields = new Set<string>()\n selectedCourse?.applicationFields?.forEach((f) => {\n if (f.showWhen?.field) {\n fields.add(f.showWhen.field)\n }\n })\n return Array.from(fields)\n }, [selectedCourse?.applicationFields])\n\n // Subscribe to watched fields to trigger re-renders when they change\n // The return value is used to trigger re-renders, not for data access\n form.watch(watchedDynamicFields as (keyof FormValues)[])\n\n // Check if a dynamic field should be visible based on showWhen condition\n function isFieldVisible(dynamicField: { showWhen?: { field?: string; value?: string } }): boolean {\n if (!dynamicField.showWhen?.field || !dynamicField.showWhen?.value) {\n return true // No condition, always visible\n }\n const watchFieldValue = form.getValues(dynamicField.showWhen.field as keyof FormValues)\n const conditionValue = dynamicField.showWhen.value\n // Handle comma-separated values as array\n const conditionValues = conditionValue.includes(',')\n ? conditionValue.split(',').map((v: string) => v.trim())\n : [conditionValue]\n return conditionValues.some((v: string) => String(watchFieldValue) === String(v))\n }\n\n // Validate required dynamic fields (not in Zod schema)\n // Returns true if there are validation errors\n function validateDynamicFields(): boolean {\n const errors: Record<string, string> = {}\n if (selectedCourse?.applicationFields) {\n for (const dynamicField of selectedCourse.applicationFields) {\n const fieldName = dynamicField.name\n // Skip validation if field is hidden by showWhen\n if (!isFieldVisible(dynamicField)) {\n continue\n }\n if (fieldName && dynamicField.required) {\n const fieldValue = form.getValues(fieldName as keyof FormValues)\n if (fieldValue === undefined || fieldValue === '' || fieldValue === null) {\n errors[fieldName] = \\`\\${dynamicField.label} is required\\`\n }\n }\n }\n }\n setDynamicFieldErrors(errors)\n return Object.keys(errors).length > 0\n }\n\n // Wrapper to validate dynamic fields before form submission\n function handleFormSubmit(e: React.FormEvent) {\n e.preventDefault()\n // Always validate dynamic fields first (sets errors immediately)\n validateDynamicFields()\n // Then let react-hook-form handle the rest\n form.handleSubmit(onSubmit)(e)\n }\n`\n : ''\n}\n function onSubmit(values: FormValues) {${\n includeDynamicFields\n ? `\n // Re-validate dynamic fields in case they were bypassed\n if (validateDynamicFields()) {\n return\n }\n\n // Collect dynamic field values from the form\n // Dynamic fields are stored in customFields JSON column\n const customFields: Record<string, unknown> = {}\n if (selectedCourse?.applicationFields) {\n for (const dynamicField of selectedCourse.applicationFields) {\n const fieldName = dynamicField.name\n if (fieldName) {\n const fieldValue = form.getValues(fieldName as keyof FormValues)\n if (fieldValue !== undefined && fieldValue !== '') {\n customFields[fieldName] = fieldValue\n }\n }\n }\n }`\n : ''\n }\n createMutation.mutate(${\n includeDynamicFields\n ? hasHiddenCourseField\n ? `{ ...values, course: selectedCourse?.title || '', customFields } as Create${pascalName}SubmissionInput`\n : `{ ...values, customFields } as Create${pascalName}SubmissionInput`\n : hasHiddenCourseField\n ? `{ ...values, course: selectedCourse?.title || '' } as Create${pascalName}SubmissionInput`\n : `values as Create${pascalName}SubmissionInput`\n })\n }\n\n return (\n <Form {...form}>\n <form id=\"${schema.name}-submission-form\" onSubmit={${includeDynamicFields ? 'handleFormSubmit' : 'form.handleSubmit(onSubmit)'}} className=\"space-y-8 w-full\">\n${formFieldsJSX}\n\n <div className=\"flex items-center gap-3 pt-5\">\n <Button\n type=\"submit\"\n variant=\"default\"\n disabled={createMutation.isPending}\n size=\"lg\"\n >\n {createMutation.isPending ? \"Submitting...\" : \"${\n schema.submitButtonText || 'Send Message'\n }\"}\n </Button>\n </div>\n </form>\n </Form>\n )\n}\n`\n\n const componentPath = path.join(paths.app, 'components/forms', `${formName}-form.tsx`)\n ensureDir(path.dirname(componentPath))\n\n if (fs.existsSync(componentPath) && !options.force) {\n console.warn(`⚠️ Form component already exists: ${componentPath}. Use --force to overwrite.`)\n return componentPath\n }\n\n fs.writeFileSync(componentPath, formContent, 'utf-8')\n console.log(` ✓ Form component generated: ${componentPath}`)\n\n return componentPath\n}\n\n/**\n * Generate multi-step form component\n */\nasync function generateMultiStepFormComponent(\n schema: FormSchema,\n options: GeneratorOptions = {}\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const formName = schema.name\n const pascalName = toPascalCase(formName)\n const steps = schema.steps || []\n const allFields = getAllFields(schema)\n\n // Determine required imports based on field types\n const hasSelect = allFields.some((f) => f.type === 'select')\n const hasCheckbox = allFields.some((f) => f.type === 'checkbox')\n const hasRadio = allFields.some((f) => f.type === 'radio')\n const hasTextarea = allFields.some((f) => f.type === 'textarea')\n const hasTimezone = allFields.some((f) => f.type === 'timezone')\n const hasList = allFields.some((f) => f.type === 'list' && (!f.fields || f.fields.length === 0))\n const hasObjectList = allFields.some((f) => f.type === 'list' && f.fields && f.fields.length > 0)\n const hasUpload = allFields.some((f) => f.type === 'upload' || f.type === 'file')\n const hasHints = allFields.some((f) => f.hint)\n const hasHiddenFields = allFields.some((f) => f.hidden)\n const includeDynamicFields = hasDynamicFields(schema)\n const hasRelationshipFields = allFields.some(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n\n // Get relationship field details\n const relationshipField = allFields.find(\n (f) => f.relationship && f.relationshipField && f.nuqsQueryParam\n )\n const relationshipHook = relationshipField?.relationship === 'courses' ? 'useCourseBySlug' : null\n\n // Check if there's a hidden course field that should get its value from selectedCourse\n const hasHiddenCourseField =\n relationshipField?.relationship === 'courses' &&\n allFields.some((f) => f.name === 'course' && f.hidden)\n\n // Generate Zod schema for all fields (filter out groups - they don't have names)\n // Make hidden course field optional (value injected at submit time)\n const zodFields = allFields\n .filter((f) => f.name)\n .map((f) => {\n const treatAsOptional = hasHiddenCourseField && f.name === 'course' && f.hidden\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n\n // Generate per-step Zod schemas (filter out groups)\n const stepSchemas = steps\n .map((step, idx) => {\n const stepFields = step.fields\n .filter((f) => f.name)\n .map((f) => {\n const treatAsOptional = hasHiddenCourseField && f.name === 'course' && f.hidden\n return ` ${f.name}: ${getZodTypeForFormField(f, { treatAsOptional })}`\n })\n .join(',\\n')\n return `const step${idx + 1}Schema = z.object({\n${stepFields}\n})`\n })\n .join('\\n\\n')\n\n // Generate default values (filter out groups - they don't have names)\n const defaultValues = allFields\n .filter((f) => f.name) // Filter out group fields which don't have names\n .map((f) => {\n let defaultVal: string\n if (f.defaultValue !== undefined) {\n defaultVal = JSON.stringify(f.defaultValue)\n } else if (f.type === 'checkbox') {\n defaultVal = 'false'\n } else if (f.type === 'number') {\n defaultVal = '0'\n } else if (f.type === 'multiselect' || f.type === 'list') {\n defaultVal = '[]'\n } else if (f.type === 'select') {\n // Select fields default to undefined so placeholder shows\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && !f.required) {\n // Optional radio fields default to undefined\n defaultVal = 'undefined'\n } else if (f.type === 'radio' && f.required && f.options && f.options.length > 0) {\n // Required radio fields default to first option value (radios don't have placeholder)\n defaultVal = `\"${f.options[0].value}\"`\n } else {\n defaultVal = '\"\"'\n }\n return ` ${f.name}: ${defaultVal}`\n })\n .join(',\\n')\n\n // Generate step components\n // Only use course colors for the 'application' form\n const useCourseColors = formName === 'application'\n const stepComponents = steps\n .map((step, idx) => {\n const stepFieldsJSX = step.fields\n .map((f) => generateFormFieldJSX(f, { useCourseColors }))\n .join('\\n\\n')\n return ` {currentStep === ${idx} && (\n <>\n <div className=\"mb-6\">\n <h3 className=\"text-lg font-semibold\">{STEPS[${idx}].label}</h3>\n ${\n step.description\n ? `<p className=\"text-sm text-muted-foreground\">${step.description}</p>`\n : ''\n }\n </div>\n <div className=\"space-y-4\">\n${stepFieldsJSX}\n </div>\n </>\n )}`\n })\n .join('\\n\\n')\n\n const formContent = `'use client'\n\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport {\n Button,\n Card,\n CardContent,\n ${hasCheckbox ? 'Checkbox,' : ''}\n ${hasList ? 'DynamicListField,' : ''}\n ${hasObjectList ? 'DynamicObjectListField,' : ''}\n ${hasUpload ? 'FileUploadField,' : ''}\n Form,\n FormControl,\n ${hasHints ? 'FormDescription,' : ''}\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n Input,\n ${hasRadio || includeDynamicFields ? 'Label,' : ''}\n ${hasRadio || includeDynamicFields ? 'RadioGroup, RadioGroupItem,' : ''}\n ${hasSelect || includeDynamicFields ? 'Select, SelectContent, SelectItem, SelectTrigger, SelectValue,' : ''}\n ${hasTextarea ? 'Textarea,' : ''}\n Tabs,\n TabsList,\n TabsTrigger,\n ${hasTimezone ? 'TimezoneSelect' : ''}\n} from '${ir.webUi}'\nimport { useCreate${pascalName}Submission, useLocalStorage${\n relationshipHook ? `, ${relationshipHook}` : ''\n } } from '${ir.hooks}'${hasHints ? `\\nimport { renderMarkdownInline } from '${ir.lib}'` : ''}\nimport { parseAsInteger, useQueryState } from 'nuqs'\nimport React from 'react'\nimport { useForm } from 'react-hook-form'\nimport { z } from 'zod'\n\n// Full form schema\nconst formSchema = z.object({\n${zodFields}\n})\n\n// Per-step schemas for validation\n${stepSchemas}\n\ntype FormValues = z.infer<typeof formSchema>\n\nconst STEPS = ${JSON.stringify(steps.map((s) => ({ name: s.name, label: s.label })))}\nconst TOTAL_STEPS = ${steps.length}\n\nexport function ${pascalName}Form() {\n const createMutation = useCreate${pascalName}Submission()\n const [isPending, startTransition] = React.useTransition()\n const [currentStep, setCurrentStep] = useQueryState('step', parseAsInteger.withDefault(0))\n ${\n hasRelationshipFields || hasHiddenFields\n ? `\n // Query state for relationship fields\n const [courseSlug] = useQueryState('course')\n ${relationshipHook ? `const { data: selectedCourse } = ${relationshipHook}(courseSlug)` : ''}`\n : ''\n }\n \n // LocalStorage persistence\n const storage = useLocalStorage<Partial<FormValues>>('form-${formName}-draft')\n\n const form = useForm<FormValues>({\n resolver: zodResolver(formSchema),\n defaultValues: storage.getItem() || {\n${defaultValues}\n }\n })\n\n // Auto-save to localStorage on field changes\n const formValues = form.watch()\n React.useEffect(() => {\n storage.setItem(formValues)\n }, [formValues, storage])\n ${\n hasRelationshipFields && relationshipField\n ? `\n // Generate tier options from selected course\n const ${relationshipField.relationshipField}Options = React.useMemo(() => {\n if (!selectedCourse?.${relationshipField.relationshipField}) return []\n return selectedCourse.${relationshipField.relationshipField}.map((tier) => ({\n value: tier.name || '',\n label: \\`\\${tier.name} - \\${tier.upfrontFee} upfront / \\${tier.monthlyFee} monthly\\`\n }))\n }, [selectedCourse])\n\n // Auto-select first tier option when tiers load or course changes\n React.useEffect(() => {\n if (${relationshipField.relationshipField}Options.length > 0) {\n const currentValue = form.getValues('${relationshipField.name}')\n const isValidOption = ${relationshipField.relationshipField}Options.some(opt => opt.value === currentValue)\n if (!currentValue || !isValidOption) {\n form.setValue('${relationshipField.name}', ${relationshipField.relationshipField}Options[0].value)\n }\n }\n }, [${relationshipField.relationshipField}Options, form])`\n : ''\n }\n\n const validateStep = React.useCallback(async (step: number) => {\n const stepFieldNames = STEPS[step] ? ${JSON.stringify(\n steps.map((s) => {\n const flattenFieldNames = (flds: FormField[]): string[] => {\n return flds.flatMap((f) => {\n if (f.type === 'group' && f.fields) {\n return flattenFieldNames(f.fields)\n }\n return f.name ? [f.name] : []\n })\n }\n return flattenFieldNames(s.fields)\n })\n )}[step] : []\n const isValid = await form.trigger(stepFieldNames.length > 0 ? stepFieldNames : undefined)\n return isValid\n }, [form])\n\n const handleNext = React.useCallback(async () => {\n const isValid = await validateStep(currentStep)\n if (isValid && currentStep < TOTAL_STEPS - 1) {\n setCurrentStep(currentStep + 1)\n }\n }, [currentStep, validateStep, setCurrentStep])\n\n const handlePrevious = React.useCallback(() => {\n if (currentStep > 0) {\n setCurrentStep(currentStep - 1)\n }\n }, [currentStep, setCurrentStep])\n\n const onSubmit = async (data: FormValues) => {\n // Final validation\n const isValid = await form.trigger()\n if (!isValid) return\n\n startTransition(() => {\n createMutation.mutate(${\n hasHiddenCourseField ? `{ ...data, course: selectedCourse?.title || '' }` : 'data'\n }, {\n onSuccess: () => {\n // Clear localStorage on successful submission\n storage.removeItem()\n form.reset()\n }\n })\n })\n }\n\n return (\n <div className=\"mx-auto max-w-2xl\">\n {/* Stepper/Tabs */}\n <Tabs value={currentStep.toString()} className=\"mb-8\">\n <TabsList className=\"grid w-full grid-cols-${steps.length}\">\n {STEPS.map((step, index) => (\n <TabsTrigger\n key={step.name}\n value={index.toString()}\n onClick={() => setCurrentStep(index)}\n disabled={index > currentStep}\n >\n {step.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n\n {/* Progress Indicator */}\n <div className=\"mb-6\">\n <p className=\"text-sm text-muted-foreground\">\n Step {currentStep + 1} of {TOTAL_STEPS}\n </p>\n </div>\n\n <Card>\n <CardContent className=\"pt-6\">\n <Form {...form}>\n <form id=\"${schema.name}-submission-multistep-form\" onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-6\">\n {/* Step Content */}\n${stepComponents}\n\n {/* Navigation Buttons */}\n <div className=\"flex justify-between pt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handlePrevious}\n disabled={currentStep === 0}\n >\n Previous\n </Button>\n\n {currentStep < TOTAL_STEPS - 1 ? (\n <Button type=\"button\" onClick={handleNext}>\n Next\n </Button>\n ) : (\n <Button type=\"submit\" disabled={isPending}>\n {isPending ? 'Submitting...' : '${schema.submitButtonText || 'Submit'}'}\n </Button>\n )}\n </div>\n </form>\n </Form>\n </CardContent>\n </Card>\n </div>\n )\n}\n`\n\n const componentPath = path.join(paths.app, 'components/forms', `${formName}-form.tsx`)\n ensureDir(path.dirname(componentPath))\n\n if (fs.existsSync(componentPath) && !options.force) {\n console.warn(`⚠️ Form component already exists: ${componentPath}. Use --force to overwrite.`)\n return componentPath\n }\n\n fs.writeFileSync(componentPath, formContent, 'utf-8')\n console.log(` ✓ Multi-step form component generated: ${componentPath}`)\n\n return componentPath\n}\n\n/**\n * Main form generation orchestrator\n */\nexport async function generateForm(\n formName: string,\n options: GeneratorOptions = {}\n): Promise<void> {\n const paths = getPaths()\n const schemaPath = path.join(paths.schemas, 'forms', `${formName}.json`)\n\n if (!fs.existsSync(schemaPath)) {\n throw new Error(`Form schema not found: ${schemaPath}`)\n }\n\n const schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n const schema: FormSchema = JSON.parse(schemaContent)\n\n console.log(`\\n📝 Generating form: ${schema.label}\\n`)\n\n try {\n // 1. Generate database schema\n console.log('1️⃣ Generating database schema...')\n await generateFormDatabase(schema, options)\n\n // 2. Generate server actions\n console.log('2️⃣ Generating server actions...')\n await generateFormActions(schema, options)\n\n // 3. Generate React Query hook\n console.log('3️⃣ Generating React Query hook...')\n await generateFormHook(schema, options)\n\n // 4. Generate form component\n console.log('4️⃣ Generating form component...')\n await generateFormComponent(schema, options)\n\n // 5. Generate email template if notificationEmail is set\n if (schema.notificationEmail) {\n console.log('5️⃣ Generating email template...')\n await generateEmailTemplate(schema, options)\n }\n\n // 6. Generate admin UI (columns, table, page)\n console.log('6️⃣ Generating admin UI...')\n // Admin UI generation will be simplified for MVP\n\n // 7. Update navigation\n console.log('7️⃣ Updating navigation...')\n await updateFormNavigation(schema, options)\n\n // 7. Generate admin UI pages\n console.log('\\n🎨 Generating admin UI pages...')\n await generateFormAdminPages(schema, options)\n\n console.log('\\n✅ Form generation complete!\\n')\n console.log('📁 Generated files:')\n console.log(` - Database schema updated`)\n console.log(` - Actions: packages/lib/src/actions/${formName}-form.ts`)\n console.log(` - Hook: packages/hooks/src/use-${formName}-form.ts`)\n console.log(` - Component: apps/web/components/forms/${formName}-form.tsx`)\n if (schema.notificationEmail) {\n console.log(` - Email template: apps/web/emails/${formName}-submission.tsx`)\n }\n console.log(` - Navigation updated (Forms group)`)\n\n // Run database migrations if not skipped\n if (!options.skipMigration) {\n console.log('\\n🗄️ Running database migrations...')\n\n // Check if DATABASE_URL is configured\n if (!process.env.DATABASE_URL) {\n console.warn('\\n⚠️ DATABASE_URL environment variable not found')\n console.warn(' Skipping database migration')\n console.warn(' To run migrations later:')\n console.warn(' 1. Configure DATABASE_URL in your .env file')\n console.warn(' 2. Run: pnpm db:push')\n } else {\n try {\n const { execSync } = await import('node:child_process')\n execSync('pnpm db:push', {\n cwd: paths.root,\n stdio: 'inherit'\n })\n console.log('\\n ✓ Database schema synced')\n } catch (error) {\n console.error('\\n⚠️ Database migration failed')\n const errorMessage = error instanceof Error ? error.message : String(error)\n console.error(' You can run manually: pnpm db:push')\n console.error(` Error: ${errorMessage}`)\n }\n }\n }\n\n // Run linter and formatter as final step\n console.log('\\n🎨 Running formatter and linter...')\n try {\n const { execSync } = await import('node:child_process')\n execSync('pnpm lint:fix', {\n cwd: paths.root,\n stdio: 'pipe'\n })\n console.log(' ✓ Code formatted and linted with Biome')\n } catch (_error) {\n console.warn(' ⚠️ Linter encountered issues (this is usually fine)')\n console.warn(' You can run: pnpm lint:fix manually if needed')\n }\n\n console.log('\\n📝 Next steps:')\n console.log(` 1. Review the generated files`)\n console.log(\n ` 2. Set up environment variables (RESEND_API_KEY, NOTIFICATION_EMAIL, FROM_EMAIL)`\n )\n console.log(` 3. Import and use the form component in your app:`)\n console.log(\n ` import { ${toPascalCase(formName)}Form } from '@/components/forms/${formName}-form'`\n )\n console.log('')\n } catch (error) {\n console.error('\\n❌ Form generation failed:', error)\n throw error\n }\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { FormSchema, GeneratorOptions } from '../types'\nimport { ensureDir, getPaths, toKebabCase } from '../utils'\n\ninterface NavigationSubItem {\n title: string\n url: string\n icon?: string\n}\n\ninterface NavigationItem {\n title: string\n url: string\n icon: string\n items?: NavigationSubItem[]\n}\n\n/**\n * Parse the existing navigation.ts file and extract navigation items\n */\nfunction parseNavigationFile(content: string): NavigationItem[] {\n // Extract the array content between [ and ] after 'export const adminNavigation ='\n const match = content.match(/export const adminNavigation\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*as const/)\n if (!match) {\n return []\n }\n\n const arrayContent = match[1]\n\n // Parse each navigation item object\n const items: NavigationItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < arrayContent.length; i++) {\n const char = arrayContent[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n // Parse the current item\n const item = parseNavigationItem(currentItem)\n if (item) {\n items.push(item)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return items\n}\n\n/**\n * Parse a single navigation item object string\n */\nfunction parseNavigationItem(itemStr: string): NavigationItem | null {\n const titleMatch = itemStr.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = itemStr.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = itemStr.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!titleMatch || !urlMatch || !iconMatch) {\n return null\n }\n\n const item: NavigationItem = {\n title: titleMatch[1],\n url: urlMatch[1],\n icon: iconMatch[1]\n }\n\n // Check for nested items array\n const itemsMatch = itemStr.match(/items:\\s*\\[([\\s\\S]*?)\\]/)\n if (itemsMatch) {\n item.items = parseSubItems(itemsMatch[1])\n }\n\n return item\n}\n\n/**\n * Parse sub-items from an items array string\n */\nfunction parseSubItems(itemsStr: string): NavigationSubItem[] {\n const subItems: NavigationSubItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < itemsStr.length; i++) {\n const char = itemsStr[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n const titleMatch = currentItem.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = currentItem.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = currentItem.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (titleMatch && urlMatch) {\n const subItem: NavigationSubItem = {\n title: titleMatch[1],\n url: urlMatch[1]\n }\n if (iconMatch) {\n subItem.icon = iconMatch[1]\n }\n subItems.push(subItem)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return subItems\n}\n\n/**\n * Generate TypeScript code for navigation items\n */\nfunction generateNavigationCode(items: NavigationItem[]): string {\n const lines: string[] = [\n \"import type { AdminNavigationItem } from '../types'\",\n '',\n 'export const adminNavigation = ['\n ]\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n\n if (item.items && item.items.length > 0) {\n // Item with sub-items\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}',`)\n lines.push(' items: [')\n\n for (let j = 0; j < item.items.length; j++) {\n const subItem = item.items[j]\n const isLastSub = j === item.items.length - 1\n lines.push(' {')\n lines.push(` title: '${subItem.title}',`)\n lines.push(` url: '${subItem.url}'${subItem.icon ? ',' : ''}`)\n if (subItem.icon) {\n lines.push(` icon: '${subItem.icon}'`)\n }\n lines.push(` }${isLastSub ? '' : ','}`)\n }\n\n lines.push(' ]')\n lines.push(` }${isLast ? '' : ','}`)\n } else {\n // Simple item\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}'`)\n lines.push(` }${isLast ? '' : ','}`)\n }\n }\n\n lines.push('] as const satisfies readonly AdminNavigationItem[]')\n lines.push('')\n\n return lines.join('\\n')\n}\n\n/**\n * Update navigation.ts to include form submission item in Forms group\n */\nexport async function updateFormNavigation(\n schema: FormSchema,\n options: GeneratorOptions\n): Promise<void> {\n const paths = getPaths()\n const navFilePath = path.join(paths.data, 'src/admin/navigation.ts')\n\n // Read existing navigation\n let navigation: NavigationItem[] = []\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n navigation = parseNavigationFile(content)\n }\n\n // Find or create Forms group\n let formsGroup = navigation.find((item) => item.title === 'Forms')\n\n if (!formsGroup) {\n formsGroup = {\n title: 'Forms',\n url: '#',\n icon: 'FileInput',\n items: []\n }\n navigation.push(formsGroup)\n }\n\n // Ensure items array exists\n if (!formsGroup.items) {\n formsGroup.items = []\n }\n\n // Create form submissions menu item\n const kebabName = toKebabCase(schema.name)\n const submissionUrl = `/admin/forms/${kebabName}`\n const existingIndex = formsGroup.items.findIndex((item) => item.url === submissionUrl)\n\n const newItem: NavigationSubItem = {\n title: schema.label,\n url: submissionUrl,\n icon: 'Inbox'\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n // Update existing item\n formsGroup.items[existingIndex] = newItem\n } else {\n console.warn(\n ` ⚠️ Navigation item already exists for \"${schema.name}\" submissions. Use --force to overwrite.`\n )\n return\n }\n } else {\n // Add new item and sort alphabetically\n formsGroup.items.push(newItem)\n formsGroup.items.sort((a, b) => a.title.localeCompare(b.title))\n }\n\n // Reorganize navigation: Home, Forms (if exists), other items alphabetically, Users last\n const home = navigation.find((item) => item.url === '/admin')\n const forms = navigation.find((item) => item.title === 'Forms')\n const users = navigation.find((item) => item.title === 'Users')\n const others = navigation.filter(\n (item) => item.url !== '/admin' && item.title !== 'Forms' && item.title !== 'Users'\n )\n\n others.sort((a, b) => a.title.localeCompare(b.title))\n\n navigation = [\n ...(home ? [home] : []),\n ...(forms ? [forms] : []),\n ...others,\n ...(users ? [users] : [])\n ]\n\n // Generate and write updated navigation\n const code = generateNavigationCode(navigation)\n ensureDir(path.dirname(navFilePath))\n fs.writeFileSync(navFilePath, code, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toPascalCase\n} from '../utils'\nimport { flattenFields } from './shared-utils'\n\n/**\n * Generate React Query hooks in packages/hooks/src/\n */\nexport async function generateHook(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const hooksDir = path.join(paths.hooks, 'src')\n ensureDir(hooksDir)\n\n const hookFileName = `use-${schema.name}.ts`\n const hookFilePath = path.join(hooksDir, hookFileName)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\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\n const singularHookName = `use${pascalSingular}`\n const singularHookContent = `\nexport function ${singularHookName}(id: number | null | undefined): UseQueryResult<${pascalSingular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singularName}', id],\n queryFn: () => (id ? get${pascalSingular}ById(id) : Promise.resolve(null)),\n enabled: !!id,\n staleTime: 0 // Refetch when query is invalidated\n })\n}\n`\n\n const slugHookName = `use${pascalSingular}BySlug`\n const slugHookContent = hasSlugField\n ? `\nexport function ${slugHookName}(slug: string | null | undefined): UseQueryResult<${pascalSingular}Data | null, Error> {\n return useQuery({\n queryKey: ['${singularName}', 'slug', slug],\n queryFn: () => (slug ? get${pascalSingular}BySlug(slug) : Promise.resolve(null)),\n enabled: !!slug,\n staleTime: 0 // Refetch when query is invalidated\n })\n}\n`\n : ''\n\n // Check if file exists\n if (fs.existsSync(hookFilePath)) {\n const existingContent = fs.readFileSync(hookFilePath, 'utf-8')\n let updatedContent = existingContent\n let hasUpdates = false\n\n // If singular hook is missing, add it\n if (!existingContent.includes(`export function ${singularHookName}(`)) {\n const importRegex = new RegExp(`import\\\\s*{([^}]+)}\\\\s*from\\\\s*['\"]${ir.libEscaped}['\"]`)\n const match = updatedContent.match(importRegex)\n\n if (match) {\n const imports = match[1].trim()\n const needsFunction = !imports.includes(`get${pascalSingular}ById`)\n const needsType = !imports.includes(`${pascalSingular}Data`)\n\n if (needsFunction || needsType) {\n let newImports = imports\n if (needsFunction) {\n newImports += `, get${pascalSingular}ById`\n }\n if (needsType) {\n newImports += `, type ${pascalSingular}Data`\n }\n updatedContent = updatedContent.replace(\n importRegex,\n `import { ${newImports} } from \"${ir.lib}\"`\n )\n }\n }\n\n // Ensure UseQueryResult is imported from react-query\n if (!updatedContent.includes('UseQueryResult')) {\n const reactQueryImportRegex = /import\\s*{([^}]+)}\\s*from\\s*['\"]@tanstack\\/react-query['\"]/\n const rqMatch = updatedContent.match(reactQueryImportRegex)\n if (rqMatch) {\n const newImports = `type UseQueryResult, ${rqMatch[1].trim()}`\n updatedContent = updatedContent.replace(\n reactQueryImportRegex,\n `import { ${newImports} } from \"@tanstack/react-query\"`\n )\n }\n }\n\n updatedContent = updatedContent.trimEnd() + singularHookContent\n hasUpdates = true\n }\n\n // If slug hook is missing and schema has slug field, add it\n if (hasSlugField && !existingContent.includes(`export function ${slugHookName}(`)) {\n const importRegex = new RegExp(`import\\\\s*{([^}]+)}\\\\s*from\\\\s*['\"]${ir.libEscaped}['\"]`)\n const match = updatedContent.match(importRegex)\n\n if (match) {\n const imports = match[1].trim()\n const needsFunction = !imports.includes(`get${pascalSingular}BySlug`)\n\n if (needsFunction) {\n let newImports = imports\n newImports += `, get${pascalSingular}BySlug`\n updatedContent = updatedContent.replace(\n importRegex,\n `import { ${newImports} } from \"${ir.lib}\"`\n )\n }\n }\n\n updatedContent = updatedContent.trimEnd() + slugHookContent\n hasUpdates = true\n }\n\n if (hasUpdates) {\n fs.writeFileSync(hookFilePath, updatedContent, 'utf-8')\n console.log(` ✅ Updated hooks in: ${hookFileName}`)\n return `packages/hooks/src/${hookFileName}`\n }\n\n if (!options.force) {\n console.warn(` ⚠️ Hook file already exists: ${hookFileName}. Use --force to overwrite.`)\n return `packages/hooks/src/${hookFileName}`\n }\n }\n\n // Check if schema has filters\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // Generate distinct values hooks for filters (each filter has its own dedicated server action)\n const distinctValuesHooks = hasFilters\n ? schema\n .filters!.map((filter) => {\n const pascalField = toPascalCase(filter.field)\n return `\nexport function use${pascalPlural}Distinct${pascalField}(): UseQueryResult<string[], Error> {\n return useQuery({\n queryKey: ['${pluralName}', 'distinct', '${filter.field}'],\n queryFn: () => getDistinct${pascalPlural}${pascalField}()\n })\n}`\n })\n .join('\\n')\n : ''\n\n // Generate full content for new file or --force overwrite\n const importFunctions = hasSlugField\n ? `get${pascalSingular}ById, get${pascalSingular}BySlug, get${pascalPlural}`\n : `get${pascalSingular}ById, get${pascalPlural}`\n\n // Import each distinct function for each filter field\n const importDistinctFunctions = hasFilters\n ? schema.filters!.map((f) => `getDistinct${pascalPlural}${toPascalCase(f.field)}`).join(', ')\n : ''\n const importDistinctFunction = hasFilters ? `, ${importDistinctFunctions}` : ''\n\n // Build filter parameters for use hook\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\n const filtersObject = hasFilters\n ? `const filters: Get${pascalPlural}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${pascalPlural}(Object.keys(filters).length > 0 ? filters : undefined)`\n : `const filters: Get${pascalPlural}Filters | undefined = search ? { search } : undefined\n return get${pascalPlural}(filters)`\n\n const content = `import {\n ${importFunctions}${importDistinctFunction},\n type ${pascalSingular}Data,\n type ${pascalPlural}Response,\n type Get${pascalPlural}Filters\n} from '${ir.actions(schema.name)}'\nimport { type UseQueryResult, useQuery } from '@tanstack/react-query'\n\nexport function use${pascalPlural}(\n ${allParams ? `${allParams},` : ''}\n options?: { enabled?: boolean }\n): UseQueryResult<${pascalPlural}Response, Error> {\n return useQuery({\n queryKey: ['${pluralName}', ${queryKeyParts}],\n queryFn: () => {\n ${filtersObject}\n },\n enabled: options?.enabled ?? true,\n refetchOnMount: 'always'\n })\n}\n${singularHookContent}${slugHookContent}${distinctValuesHooks}`\n\n fs.writeFileSync(hookFilePath, content, 'utf-8')\n\n // Update hooks/src/index.ts to export new hook\n const indexPath = path.join(hooksDir, 'index.ts')\n const exportLine = `export * from './${hookFileName.replace('.ts', '')}'`\n\n if (fs.existsSync(indexPath)) {\n let indexContent = fs.readFileSync(indexPath, 'utf-8')\n if (!indexContent.includes(exportLine)) {\n indexContent += `${exportLine}\\n`\n fs.writeFileSync(indexPath, indexContent, 'utf-8')\n }\n } else {\n fs.writeFileSync(indexPath, `${exportLine}\\n`, 'utf-8')\n }\n\n return `packages/hooks/src/${hookFileName}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport { ensureDir, getPaths } from '../utils'\n\ninterface NavigationSubItem {\n title: string\n url: string\n icon?: string\n}\n\ninterface NavigationItem {\n title: string\n url: string\n icon: string\n items?: NavigationSubItem[]\n}\n\n/**\n * Parse the existing navigation.ts file and extract navigation items\n */\nfunction parseNavigationFile(content: string): NavigationItem[] {\n // Extract the array content between [ and ] after 'export const adminNavigation ='\n const match = content.match(/export const adminNavigation\\s*=\\s*\\[([\\s\\S]*?)\\]\\s*as const/)\n if (!match) {\n return []\n }\n\n const arrayContent = match[1]\n\n // Parse each navigation item object\n const items: NavigationItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < arrayContent.length; i++) {\n const char = arrayContent[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n // Parse the current item\n const item = parseNavigationItem(currentItem)\n if (item) {\n items.push(item)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return items\n}\n\n/**\n * Parse a single navigation item object string\n */\nfunction parseNavigationItem(itemStr: string): NavigationItem | null {\n const titleMatch = itemStr.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = itemStr.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = itemStr.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (!titleMatch || !urlMatch || !iconMatch) {\n return null\n }\n\n const item: NavigationItem = {\n title: titleMatch[1],\n url: urlMatch[1],\n icon: iconMatch[1]\n }\n\n // Check for nested items array\n const itemsMatch = itemStr.match(/items:\\s*\\[([\\s\\S]*?)\\]/)\n if (itemsMatch) {\n item.items = parseSubItems(itemsMatch[1])\n }\n\n return item\n}\n\n/**\n * Parse sub-items from an items array string\n */\nfunction parseSubItems(itemsStr: string): NavigationSubItem[] {\n const subItems: NavigationSubItem[] = []\n let depth = 0\n let currentItem = ''\n let inObject = false\n\n for (let i = 0; i < itemsStr.length; i++) {\n const char = itemsStr[i]\n\n if (char === '{') {\n if (depth === 0) {\n inObject = true\n }\n depth++\n currentItem += char\n } else if (char === '}') {\n depth--\n currentItem += char\n if (depth === 0 && inObject) {\n const titleMatch = currentItem.match(/title:\\s*['\"]([^'\"]+)['\"]/)\n const urlMatch = currentItem.match(/url:\\s*['\"]([^'\"]+)['\"]/)\n const iconMatch = currentItem.match(/icon:\\s*['\"]([^'\"]+)['\"]/)\n\n if (titleMatch && urlMatch) {\n const subItem: NavigationSubItem = {\n title: titleMatch[1],\n url: urlMatch[1]\n }\n if (iconMatch) {\n subItem.icon = iconMatch[1]\n }\n subItems.push(subItem)\n }\n currentItem = ''\n inObject = false\n }\n } else if (inObject) {\n currentItem += char\n }\n }\n\n return subItems\n}\n\n/**\n * Generate TypeScript code for navigation items\n */\nfunction generateNavigationCode(items: NavigationItem[]): string {\n const lines: string[] = [\n \"import type { AdminNavigationItem } from '../types'\",\n '',\n 'export const adminNavigation = ['\n ]\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n const isLast = i === items.length - 1\n\n if (item.items && item.items.length > 0) {\n // Item with sub-items\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}',`)\n lines.push(' items: [')\n\n for (let j = 0; j < item.items.length; j++) {\n const subItem = item.items[j]\n const isLastSub = j === item.items.length - 1\n lines.push(' {')\n lines.push(` title: '${subItem.title}',`)\n lines.push(` url: '${subItem.url}'${subItem.icon ? ',' : ''}`)\n if (subItem.icon) {\n lines.push(` icon: '${subItem.icon}'`)\n }\n lines.push(` }${isLastSub ? '' : ','}`)\n }\n\n lines.push(' ]')\n lines.push(` }${isLast ? '' : ','}`)\n } else {\n // Simple item\n lines.push(' {')\n lines.push(` title: '${item.title}',`)\n lines.push(` url: '${item.url}',`)\n lines.push(` icon: '${item.icon}'`)\n lines.push(` }${isLast ? '' : ','}`)\n }\n }\n\n lines.push('] as const satisfies readonly AdminNavigationItem[]')\n lines.push('')\n\n return lines.join('\\n')\n}\n\n/**\n * Update navigation.ts to include new menu item\n */\nexport async function updateNavigation(schema: Schema, options: GeneratorOptions): Promise<void> {\n const paths = getPaths()\n const navFilePath = path.join(paths.data, 'src/admin/navigation.ts')\n\n // Read existing navigation\n let navigation: NavigationItem[] = []\n if (fs.existsSync(navFilePath)) {\n const content = fs.readFileSync(navFilePath, 'utf-8')\n navigation = parseNavigationFile(content)\n }\n\n // Check if item already exists\n const existingIndex = navigation.findIndex((item) => item.url === `/admin/${schema.name}`)\n\n const newItem: NavigationItem = {\n title: schema.label,\n url: `/admin/${schema.name}`,\n icon: schema.icon\n }\n\n if (existingIndex >= 0) {\n if (options.force) {\n // Update existing item\n navigation[existingIndex] = newItem\n } else {\n console.warn(\n ` ⚠️ Navigation item already exists for \"${schema.name}\". Use --force to overwrite.`\n )\n return\n }\n } else {\n // Add new item and sort alphabetically (except Home should always be first, Forms second, Users last)\n const home = navigation.find((item) => item.url === '/admin')\n const forms = navigation.find((item) => item.title === 'Forms')\n const users = navigation.find((item) => item.title === 'Users')\n const others = navigation.filter(\n (item) => item.url !== '/admin' && item.title !== 'Forms' && item.title !== 'Users'\n )\n\n others.push(newItem)\n others.sort((a, b) => a.title.localeCompare(b.title))\n\n navigation = [\n ...(home ? [home] : []),\n ...(forms ? [forms] : []),\n ...others,\n ...(users ? [users] : [])\n ]\n }\n\n // Generate and write updated navigation\n const code = generateNavigationCode(navigation)\n ensureDir(path.dirname(navFilePath))\n fs.writeFileSync(navFilePath, code, 'utf-8')\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport { ensureDir, getPaths, pluralize, toKebabCase, toPascalCase } from '../utils'\n\n/**\n * Generate page component\n */\nexport async function generatePage(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const pageFilePath = path.join(adminDir, 'page.tsx')\n\n // Check if file exists\n if (fs.existsSync(pageFilePath) && !options.force) {\n console.warn(` ⚠️ Page file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/page.tsx`\n }\n\n const pluralName = pluralize(schema.name)\n const pascalPlural = toPascalCase(pluralName)\n const tableFileName = toKebabCase(pluralName)\n\n const content = `import * as React from \"react\";\nimport { AdminSubHeader } from \"@/components/admin\";\nimport { AdminPageSkeleton } from \"@/components/admin/admin-page-skeleton\";\nimport { columns } from \"./columns\";\nimport { ${pascalPlural}PageContent } from \"./${tableFileName}-page-content\";\n\nexport default function Page() {\n return (\n <React.Suspense fallback={<AdminPageSkeleton />}>\n <div className=\"flex flex-col\">\n <AdminSubHeader />\n <${pascalPlural}PageContent columns={columns} />\n </div>\n </React.Suspense>\n );\n}\n`\n\n fs.writeFileSync(pageFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/page.tsx`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n singularizeLabel,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate page content component (client component with state management)\n */\nexport async function generatePageContent(\n schema: Schema,\n options: GeneratorOptions\n): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const fileName = `${toKebabCase(pluralName)}-page-content.tsx`\n const filePath = path.join(adminDir, fileName)\n\n // Check if file exists\n if (fs.existsSync(filePath) && !options.force) {\n console.warn(` ⚠️ Page content file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${fileName}`\n }\n\n const hasCreateAction = schema.actions?.create ?? false\n const hasDeleteAction = schema.actions?.delete ?? false\n const hasFilters = schema.filters && schema.filters.length > 0\n\n // Generate lucide icons list\n const lucideIcons: string[] = ['Search']\n if (hasCreateAction) lucideIcons.push('FilePlus')\n if (hasDeleteAction) lucideIcons.push('Trash2')\n if (hasFilters) lucideIcons.push('Check', 'ChevronsUpDown')\n\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${hasCreateAction ? \"import Link from 'next/link'\\n\" : ''}import { parseAsString${hasDeleteAction ? ', parseAsArrayOf, parseAsInteger' : ''}, useQueryState } from 'nuqs'\nimport * as React from 'react'\nimport { useFormStatus } from 'react-dom'\n${\n hasDeleteAction ? \"import { toast } from 'sonner'\\n\" : ''\n}import { AdminPageHeader } from '@/components/admin'\n`\n\n if (hasDeleteAction) {\n imports += `import {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n AlertDialogTrigger,\n Button,\n Input${\n hasFilters\n ? `,\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n Popover,\n PopoverContent,\n PopoverTrigger`\n : ''\n }\n} from '${ir.adminUi}'\n`\n } else {\n // Always need Button for search submit\n imports += `import { Button, Input${\n hasFilters\n ? `, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger`\n : ''\n } } from '${ir.adminUi}'\\n`\n }\n\n // Add filter hooks import\n const filterHooksImport = hasFilters\n ? schema.filters!.map((f) => `use${pascalPlural}Distinct${toPascalCase(f.field)}`).join(', ')\n : ''\n\n imports += `${\n hasFilters ? `import { ${filterHooksImport} } from '${ir.hooks}'\\n` : ''\n }import type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\n${\n hasDeleteAction ? `import { deleteBulk${pascalPlural} } from '${ir.actions(schema.name)}'\\n` : ''\n}${hasFilters ? `import { cn } from '${ir.utils}'\\n` : ''}import { ${pascalPlural}Table } from './${toKebabCase(pluralName)}-table'\n`\n\n const queryClientLogic = hasDeleteAction ? ` const queryClient = useQueryClient()` : ''\n\n // SearchButton component using useFormStatus\n const searchButtonComponent = `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 management\n const filterLogic = hasFilters\n ? schema\n .filters!.map((filter) => {\n return ` const [${filter.field}, set${toPascalCase(filter.field)}] = useQueryState('${filter.field}', parseAsString.withDefault(''))\n const { data: ${filter.field}Options } = use${pascalPlural}Distinct${toPascalCase(filter.field)}()\n const [${filter.field}ComboboxOpen, set${toPascalCase(filter.field)}ComboboxOpen] = React.useState(false)`\n })\n .join('\\n')\n : ''\n\n // Search state management - action-based\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`\n\n const deleteLogic = hasDeleteAction\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${pascalPlural}(selectedIds)\n\n if (result.success) {\n toast.success(\n \\`\\${selectedIds.length} ${singularName}\\${selectedIds.length > 1 ? 's' : ''} deleted successfully\\`\n )\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\n setSelectedIds([])\n setDeleteDialogOpen(false)\n } else {\n toast.error(result.error || 'Failed to delete ${pluralName}')\n }\n } catch (error) {\n toast.error('An error occurred')\n console.error(error)\n }\n })\n }\n`\n : ''\n\n const deleteButton = hasDeleteAction\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 ? '${singularName}' : '${pluralName}'}\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 ? '${singularName}' : '${pluralName}'}.\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 const createButton = hasCreateAction\n ? ` <Button asChild>\n <Link href=\"/admin/${schema.name}/new\">\n <FilePlus className=\"size-3.5 -ml-0.5\" strokeWidth={2} />\n Create ${singularizeLabel(schema.label)}\n </Link>\n </Button>`\n : ''\n\n // GitHub sync button removed - no longer using GitHub sync\n\n // Build table props with filters\n const filterPropsString = hasFilters\n ? schema.filters!.map((f) => `${f.field}={${f.field}}`).join(' ')\n : ''\n const allTableProps = filterPropsString\n ? `search={search} ${filterPropsString}`\n : 'search={search}'\n\n const tableProps = hasDeleteAction\n ? `columns={columns} selectedIds={selectedIds} setSelectedIds={setSelectedIds} ${allTableProps}`\n : `columns={columns} selectedIds={[]} setSelectedIds={() => {}} ${allTableProps}`\n\n // Filter dropdown components\n const filterDropdowns = hasFilters\n ? schema\n .filters!.map((filter) => {\n return ` <Popover open={${filter.field}ComboboxOpen} onOpenChange={set${toPascalCase(filter.field)}ComboboxOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={${filter.field}ComboboxOpen}\n className=\"w-[200px] justify-between\"\n >\n {${filter.field} || '${filter.label}'}\n <ChevronsUpDown className=\"ml-2 h-4 w-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(filter.field)}('')\n })\n set${toPascalCase(filter.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-4 w-4',\n ${filter.field} === '' ? 'opacity-100' : 'opacity-0'\n )}\n />\n All ${filter.label}\n </CommandItem>\n {${filter.field}Options?.map((option) => (\n <CommandItem\n key={option}\n value={option}\n onSelect={() => {\n React.startTransition(() => {\n set${toPascalCase(filter.field)}(option)\n })\n set${toPascalCase(filter.field)}ComboboxOpen(false)\n }}\n >\n <Check\n className={cn(\n 'mr-2 h-4 w-4',\n ${filter.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 form component with submit button\n const searchInput = ` <form action={searchAction} className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <Search className=\"text-muted-foreground 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\"\n />\n </div>\n <SearchButton />\n </form>`\n\n const content = `${imports}\n${searchButtonComponent}interface ${pascalPlural}PageContentProps<TValue> {\n columns: ColumnDef<${pascalSingular}Data, TValue>[]\n}\n\nexport function ${pascalPlural}PageContent<TValue>({\n columns\n}: ${pascalPlural}PageContentProps<TValue>) {\n${queryClientLogic}\n${searchLogic}${deleteLogic}\n return (\n <>\n <div className=\"flex items-center justify-between bg-card px-6 py-4 border-b\">\n <AdminPageHeader title=\"${schema.label}\" description=\"${schema.description}\" />\n <div className=\"flex items-center gap-2\">\n${filterDropdowns ? `${filterDropdowns}\\n` : ''}${searchInput}\n${deleteButton}\n${createButton}\n </div>\n </div>\n\n <main className=\"space-y-6 p-6\">\n <${pascalPlural}Table ${tableProps} />\n </main>\n </>\n )\n}\n`\n\n fs.writeFileSync(filePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${fileName}`\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport type { GeneratorOptions, Schema } from '../types'\nimport {\n ensureDir,\n getImportResolver,\n getPaths,\n pluralize,\n singularize,\n toCamelCase,\n toKebabCase,\n toPascalCase\n} from '../utils'\n\n/**\n * Generate table component\n */\nexport async function generateTable(schema: Schema, options: GeneratorOptions): Promise<string> {\n const paths = getPaths()\n const ir = getImportResolver()\n const adminDir = path.join(paths.app, 'app/(admin)/admin', schema.name)\n ensureDir(adminDir)\n\n const singularName = singularize(schema.name)\n const pluralName = pluralize(schema.name)\n const pascalSingular = toPascalCase(singularName)\n const pascalPlural = toPascalCase(pluralName)\n const camelPlural = toCamelCase(pluralName)\n const camelSingular = toCamelCase(singularName)\n const tableFileName = `${toKebabCase(pluralName)}-table.tsx`\n const tableFilePath = path.join(adminDir, tableFileName)\n\n // Check if file exists\n if (fs.existsSync(tableFilePath) && !options.force) {\n console.warn(` ⚠️ Table file already exists. Use --force to overwrite.`)\n return `app/(admin)/admin/${schema.name}/${tableFileName}`\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\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 {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow\n} from '${ir.adminUi}'\nimport { use${pascalPlural} } from '${ir.hooks}'\nimport { bulkUpdate${pascalPlural}SortOrder } from '${ir.actions(schema.name)}'\nimport type { ${pascalSingular}Data } from '${ir.actions(schema.name)}'\nimport '${ir.tableMeta}'\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 ${pascalPlural}TableProps<TValue> {\n columns: ColumnDef<${pascalSingular}Data, TValue>[]\n selectedIds: number[]\n setSelectedIds: (ids: number[]) => void\n search?: string${allFilterProps}\n}\n\nexport function ${pascalPlural}Table<TValue>({ columns, selectedIds, setSelectedIds, ${allParams} }: ${pascalPlural}TableProps<TValue>) {\n const { data, error, isPending } = use${pascalPlural}(${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<${pascalSingular}Data[]>([])\n const [hasChanges, setHasChanges] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n\n // Sync local data when server data changes or reorder mode is toggled\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 // Create array of { id, sortOrder } based on current order\n const updates = localData.map((item, index) => ({\n id: item.id as number,\n sortOrder: index\n }))\n\n const result = await bulkUpdate${pascalPlural}SortOrder(updates)\n\n if (result.success) {\n toast.success('Sort order saved successfully')\n queryClient.refetchQueries({ queryKey: ['${pluralName}'] })\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 corner-squircle\">\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 fs.writeFileSync(tableFilePath, content, 'utf-8')\n\n return `app/(admin)/admin/${schema.name}/${tableFileName}`\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { updateExports } from './exports'\nimport { getAvailableComponents, resolveRegistryDeps } from './registry'\nimport { extractFileName, transformSource } from './transform'\nimport {\n type AddComponentOptions,\n DEFAULT_TARGET,\n type RegistryItem,\n TARGET_CONFIGS\n} from './types'\n\nconst log = (message: string, silent = false) => {\n if (!silent) console.log(message)\n}\n\nconst runPnpmAdd = (deps: string[], packageFilter: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['add', ...deps, '--filter', packageFilter], {\n stdio: 'inherit',\n shell: true\n })\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n } else {\n reject(new Error(`pnpm add failed with code ${code}`))\n }\n })\n\n child.on('error', reject)\n })\n}\n\nconst runLintFix = (): Promise<void> => {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['lint:fix'], {\n stdio: 'inherit',\n shell: true\n })\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n } else {\n // Don't fail on lint errors, just warn\n console.warn('Lint fix completed with warnings')\n resolve()\n }\n })\n\n child.on('error', reject)\n })\n}\n\nexport const listComponents = async (): Promise<void> => {\n console.log('Fetching available components...\\n')\n const components = await getAvailableComponents()\n console.log('Available shadcn components:\\n')\n console.log(components.map((c) => ` - ${c}`).join('\\n'))\n console.log(`\\nTotal: ${components.length} components`)\n}\n\nexport const addComponents = async (\n componentNames: string[],\n options: AddComponentOptions = {}\n): Promise<void> => {\n const {\n overwrite = false,\n silent = false,\n skipMissing = false,\n target = DEFAULT_TARGET\n } = options\n const { componentsDir: targetComponentsDir, packageFilter } = TARGET_CONFIGS[target]\n\n if (componentNames.length === 0) {\n throw new Error('No components specified')\n }\n\n log(`Resolving dependencies for: ${componentNames.join(', ')}`, silent)\n log(`Target package: ${packageFilter}`, silent)\n\n // Resolve all dependencies recursively\n const allComponents = await resolveRegistryDeps(componentNames, new Set(), { skipMissing })\n\n // Dedupe by name\n const componentMap = new Map<string, RegistryItem>()\n for (const component of allComponents) {\n componentMap.set(component.name, component)\n }\n\n const componentsToInstall = Array.from(componentMap.values())\n log(`\\nComponents to install: ${componentsToInstall.map((c) => c.name).join(', ')}`, silent)\n\n // Ensure components directory exists\n const componentsDir = resolve(process.cwd(), targetComponentsDir)\n if (!existsSync(componentsDir)) {\n mkdirSync(componentsDir, { recursive: true })\n }\n\n // Collect all npm dependencies\n const allDeps = new Set<string>()\n const allDevDeps = new Set<string>()\n const installedComponents: string[] = []\n\n // Write component files\n for (const component of componentsToInstall) {\n for (const file of component.files) {\n const fileName = extractFileName(file.path)\n const componentName = fileName.replace(/\\.(tsx?|ts)$/, '')\n const filePath = resolve(componentsDir, fileName)\n\n if (existsSync(filePath) && !overwrite) {\n log(` Skipping ${fileName} (already exists)`, silent)\n continue\n }\n\n const transformedContent = transformSource(file.content)\n writeFileSync(filePath, transformedContent)\n log(` Created ${fileName}`, silent)\n installedComponents.push(componentName)\n }\n\n // Collect dependencies\n if (component.dependencies) {\n for (const dep of component.dependencies) {\n allDeps.add(dep)\n }\n }\n if (component.devDependencies) {\n for (const dep of component.devDependencies) {\n allDevDeps.add(dep)\n }\n }\n }\n\n // Install npm dependencies\n if (allDeps.size > 0) {\n log(`\\nInstalling dependencies: ${Array.from(allDeps).join(', ')}`, silent)\n await runPnpmAdd(Array.from(allDeps), packageFilter)\n }\n\n // Update exports\n if (installedComponents.length > 0) {\n log('\\nUpdating component exports...', silent)\n updateExports(installedComponents, target)\n }\n\n // Run lint:fix\n log('\\nRunning lint:fix...', silent)\n await runLintFix()\n\n log(`\\nDone! Installed ${installedComponents.length} component(s).`, silent)\n}\n\nexport const addAllComponents = async (options: AddComponentOptions = {}): Promise<void> => {\n const { target = DEFAULT_TARGET } = options\n const { packageFilter } = TARGET_CONFIGS[target]\n console.log('Fetching all available components...')\n console.log(`Target package: ${packageFilter}`)\n const components = await getAvailableComponents()\n console.log(`Found ${components.length} components to install\\n`)\n await addComponents(components, { ...options, skipMissing: true })\n}\n","import { readFileSync, writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { DEFAULT_TARGET, TARGET_CONFIGS, type TargetPackage } from './types'\n\nconst INDEX_FILE = 'index.ts'\n\n/**\n * Update the components index.ts to include exports for new components\n */\nexport const updateExports = (\n componentNames: string[],\n target: TargetPackage = DEFAULT_TARGET\n): void => {\n const { componentsDir } = TARGET_CONFIGS[target]\n const indexPath = resolve(process.cwd(), componentsDir, INDEX_FILE)\n\n let content: string\n try {\n content = readFileSync(indexPath, 'utf-8')\n } catch {\n content = ''\n }\n\n // Parse existing exports\n const existingExports = new Set<string>()\n const exportRegex = /export \\* from ['\"]\\.\\/([^'\"]+)['\"]/g\n const matches = content.matchAll(exportRegex)\n for (const match of matches) {\n existingExports.add(match[1])\n }\n\n // Add new exports\n for (const name of componentNames) {\n existingExports.add(name)\n }\n\n // Sort and generate new content\n const sortedExports = Array.from(existingExports).sort()\n const newContent = `${sortedExports.map((name) => `export * from './${name}'`).join('\\n')}\\n`\n\n writeFileSync(indexPath, newContent)\n}\n\n/**\n * Check if an export already exists\n */\nexport const exportExists = (\n componentName: string,\n target: TargetPackage = DEFAULT_TARGET\n): boolean => {\n const { componentsDir } = TARGET_CONFIGS[target]\n const indexPath = resolve(process.cwd(), componentsDir, INDEX_FILE)\n\n let content: string\n try {\n content = readFileSync(indexPath, 'utf-8')\n } catch {\n return false\n }\n\n return content.includes(`from './${componentName}'`)\n}\n","export interface RegistryFile {\n path: string\n content: string\n type?: string\n target?: string\n}\n\nexport interface RegistryItem {\n name: string\n type: string\n dependencies?: string[]\n devDependencies?: string[]\n registryDependencies?: string[]\n files: RegistryFile[]\n cssVars?: Record<string, Record<string, string>>\n tailwind?: {\n config?: Record<string, unknown>\n }\n}\n\nexport interface RegistryIndexItem {\n name: string\n type: string\n registryDependencies?: string[]\n dependencies?: string[]\n files?: Array<{ path: string; type: string }>\n}\n\nexport type RegistryIndex = RegistryIndexItem[]\n\nexport interface AddComponentOptions {\n overwrite?: boolean\n silent?: boolean\n skipMissing?: boolean\n target?: TargetPackage\n}\n\nexport type TargetPackage = 'web-ui' | 'admin-ui'\n\nexport interface TargetConfig {\n componentsDir: string\n packageFilter: string\n}\n\nexport const TARGET_CONFIGS: Record<TargetPackage, TargetConfig> = {\n 'web-ui': {\n componentsDir: 'packages/web-ui/src/components',\n packageFilter: '@betterstart/web-ui'\n },\n 'admin-ui': {\n componentsDir: 'packages/admin-ui/src/components',\n packageFilter: '@betterstart/admin-ui'\n }\n}\n\nexport const DEFAULT_TARGET: TargetPackage = 'web-ui'\n","import type { RegistryIndex, RegistryItem } from './types'\n\nconst REGISTRY_BASE = 'https://ui.shadcn.com/r/styles/new-york'\nconst INDEX_URL = 'https://ui.shadcn.com/r/index.json'\n\nexport const fetchComponent = async (name: string): Promise<RegistryItem> => {\n const res = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (!res.ok) {\n throw new Error(`Component \"${name}\" not found in registry (status: ${res.status})`)\n }\n return res.json() as Promise<RegistryItem>\n}\n\nexport const tryFetchComponent = async (name: string): Promise<RegistryItem | null> => {\n const res = await fetch(`${REGISTRY_BASE}/${name}.json`)\n if (!res.ok) {\n return null\n }\n return res.json() as Promise<RegistryItem>\n}\n\nexport const fetchIndex = async (): Promise<RegistryIndex> => {\n const res = await fetch(INDEX_URL)\n if (!res.ok) {\n throw new Error(`Failed to fetch registry index (status: ${res.status})`)\n }\n return res.json() as Promise<RegistryIndex>\n}\n\nexport const resolveRegistryDeps = async (\n names: string[],\n seen = new Set<string>(),\n options: { skipMissing?: boolean } = {}\n): Promise<RegistryItem[]> => {\n const items: RegistryItem[] = []\n const { skipMissing = false } = options\n\n for (const name of names) {\n if (seen.has(name)) continue\n seen.add(name)\n\n let item: RegistryItem | null\n if (skipMissing) {\n item = await tryFetchComponent(name)\n if (!item) {\n console.warn(` Skipping \"${name}\" (not found in registry)`)\n continue\n }\n } else {\n item = await fetchComponent(name)\n }\n\n // First resolve dependencies recursively\n if (item.registryDependencies?.length) {\n const deps = await resolveRegistryDeps(item.registryDependencies, seen, options)\n items.push(...deps)\n }\n\n items.push(item)\n }\n\n return items\n}\n\nexport const getAvailableComponents = async (): Promise<string[]> => {\n const index = await fetchIndex()\n return index\n .filter((item) => item.type === 'registry:ui')\n .map((item) => item.name)\n .sort()\n}\n","/**\n * Transform shadcn component source code for project compatibility\n */\nexport const transformSource = (content: string): string => {\n let result = content\n\n // Replace @/lib/utils import with @betterstart/utils\n result = result.replace(/from\\s+[\"']@\\/lib\\/utils[\"']/g, 'from \"@betterstart/utils\"')\n\n // Replace relative lib/utils imports\n result = result.replace(/from\\s+[\"']\\.\\.?\\/lib\\/utils[\"']/g, 'from \"@betterstart/utils\"')\n\n // Replace @/components/ui imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/components\\/ui\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/hooks imports with @betterstart/hooks\n result = result.replace(/from\\s+[\"']@\\/hooks\\/([^\"']+)[\"']/g, 'from \"@betterstart/hooks\"')\n\n // Replace @/registry/new-york/ui imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/registry\\/new-york\\/ui\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/registry/new-york/hooks imports with relative imports\n result = result.replace(/from\\s+[\"']@\\/registry\\/new-york\\/hooks\\/([^\"']+)[\"']/g, 'from \"./$1\"')\n\n // Replace @/registry/new-york/lib/utils import with @betterstart/utils\n result = result.replace(\n /from\\s+[\"']@\\/registry\\/new-york\\/lib\\/utils[\"']/g,\n 'from \"@betterstart/utils\"'\n )\n\n // Fix react-resizable-panels v4.x API changes (PanelGroup -> Group, PanelResizeHandle -> Separator)\n result = result.replace(/ResizablePrimitive\\.PanelGroup/g, 'ResizablePrimitive.Group')\n result = result.replace(/ResizablePrimitive\\.PanelResizeHandle/g, 'ResizablePrimitive.Separator')\n\n return result\n}\n\n/**\n * Extract the component file name from registry path\n */\nexport const extractFileName = (registryPath: string): string => {\n // Registry paths are like \"ui/button.tsx\" -> extract \"button.tsx\"\n const parts = registryPath.split('/')\n return parts[parts.length - 1]\n}\n","// Main entry point for the codegen package\n\n// Re-export config helpers for use in betterstart.config.ts\nexport { defineConfig } from './config/loader'\nexport type { UserConfig } from './config/types'\nexport * from './generators'\nexport * from './shadcn'\nexport * from './types'\nexport * from './utils'\n\n// Re-export key functions for programmatic use\nimport { execSync } from 'node:child_process'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { findProjectRoot, loadConfig, resolveConfig } from './config'\nimport {\n generateActions,\n generateCache,\n generateColumns,\n generateCreatePage,\n generateDatabase,\n generateEditPage,\n generateForm,\n generateHook,\n generatePage,\n generatePageContent,\n generateTable,\n updateNavigation\n} from './generators'\nimport { flattenFields } from './generators/shared-utils'\nimport type { GeneratorOptions, Schema } from './types'\nimport { getPaths, initImportResolver } from './utils'\n\n/**\n * Validate the schema structure\n */\nexport function validateSchema(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\n if (!schema.label || typeof schema.label !== 'string') {\n errors.push('Schema must have a valid \"label\" field')\n }\n\n if (!schema.description || typeof schema.description !== 'string') {\n errors.push('Schema must have a valid \"description\" field')\n }\n\n if (!schema.icon || typeof schema.icon !== 'string') {\n errors.push('Schema must have a valid \"icon\" field')\n }\n\n if (!Array.isArray(schema.fields) || schema.fields.length === 0) {\n errors.push('Schema must have at least one field')\n }\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') {\n continue\n }\n if (!field.name || !field.type) {\n errors.push(`Field is missing required properties: ${JSON.stringify(field)}`)\n }\n }\n\n // Validate columns\n const flattenedFields = flattenFields(schema.fields || [])\n const fieldNames = new Set(flattenedFields.map((f) => f.name))\n\n // Add special fields that might be used in columns but not in schema fields\n fieldNames.add('id') // ID is always available\n fieldNames.add('createdAt') // Timestamps are auto-added\n fieldNames.add('updatedAt')\n fieldNames.add('published') // Published is auto-added for draft mode\n fieldNames.add('submittedAt') // Submission timestamp for form submissions\n fieldNames.add('ipAddress') // IP address for form submissions\n fieldNames.add('userAgent') // User agent for form submissions\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 name. Available fields: ${Array.from(fieldNames).join(', ')}`\n )\n }\n }\n\n return errors\n}\n\n/**\n * Main generator function - generates all files for a schema\n */\nexport async function generate(schemaName: string, options: GeneratorOptions = {}): Promise<void> {\n // Use pre-seeded paths (from CLI) or fall back to auto-detection\n const paths = getPaths()\n\n // Load config and initialize import resolver\n const projectRoot = findProjectRoot(process.cwd())\n const config = await loadConfig(projectRoot)\n const resolvedConfig = resolveConfig(config, projectRoot)\n initImportResolver(resolvedConfig)\n\n const schemaPath = path.join(paths.schemas, `${schemaName}.json`)\n\n console.log('\\n🚀 Admin Codemod Generator\\n')\n console.log(`📁 Monorepo root: ${paths.root}`)\n console.log(`📄 Reading schema: ${schemaName}.json`)\n\n // Check if schema file exists\n if (!fs.existsSync(schemaPath)) {\n console.error(`❌ Schema file not found: ${schemaPath}`)\n process.exit(1)\n }\n\n // Read and parse schema\n let schema: Schema\n try {\n const schemaContent = fs.readFileSync(schemaPath, 'utf-8')\n schema = JSON.parse(schemaContent)\n } catch (error) {\n console.error(`❌ Failed to parse schema file: ${error}`)\n process.exit(1)\n }\n\n // Validate schema\n console.log('✓ Schema loaded')\n console.log('🔍 Validating schema...')\n const validationErrors = validateSchema(schema)\n if (validationErrors.length > 0) {\n console.error('\\n❌ 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')\n\n // Track generated files\n const generatedFiles: string[] = []\n\n try {\n console.log('\\n📦 Generating files...\\n')\n\n // Generate database schema and migration\n if (!options.skipMigration) {\n console.log('1️⃣ Generating database schema...')\n const dbFiles = await generateDatabase(schema, options)\n generatedFiles.push(...dbFiles)\n console.log(' ✓ Database schema generated')\n }\n\n // Generate server actions\n console.log('2️⃣ Generating server actions...')\n const actionsFile = await generateActions(schema, options)\n generatedFiles.push(actionsFile)\n console.log(' ✓ Server actions generated')\n\n // Generate React Query hook\n console.log('3️⃣ Generating React Query hook...')\n const hookFile = await generateHook(schema, options)\n generatedFiles.push(hookFile)\n console.log(' ✓ Hook generated')\n\n // Generate columns\n console.log('4️⃣ Generating table columns...')\n const columnsFile = await generateColumns(schema, options)\n generatedFiles.push(columnsFile)\n console.log(' ✓ Columns generated')\n\n // Generate table component\n console.log('5️⃣ Generating table component...')\n const tableFile = await generateTable(schema, options)\n generatedFiles.push(tableFile)\n console.log(' ✓ Table component generated')\n\n // Generate page content component\n console.log('6️⃣ Generating page content component...')\n const pageContentFile = await generatePageContent(schema, options)\n generatedFiles.push(pageContentFile)\n console.log(' ✓ Page content component generated')\n\n // Generate page component\n console.log('7️⃣ Generating page component...')\n const pageFile = await generatePage(schema, options)\n generatedFiles.push(pageFile)\n console.log(' ✓ Page component generated')\n\n // Generate form and CRUD pages if actions are enabled\n if (schema.actions?.create || schema.actions?.edit) {\n console.log('8️⃣ Generating form component...')\n const formFile = await generateForm(schema, options)\n generatedFiles.push(formFile)\n console.log(' ✓ Form component generated')\n\n if (schema.actions?.create) {\n console.log('9️⃣ Generating create page...')\n const createPageFile = await generateCreatePage(schema, options)\n generatedFiles.push(createPageFile)\n console.log(' ✓ Create page generated')\n }\n\n if (schema.actions?.edit) {\n console.log('🔟 Generating edit page...')\n const editPageFile = await generateEditPage(schema, options)\n generatedFiles.push(editPageFile)\n console.log(' ✓ Edit page generated')\n }\n }\n\n // Update navigation\n console.log('1️⃣1️⃣ Updating navigation...')\n await updateNavigation(schema, options)\n generatedFiles.push('packages/data/src/admin/navigation.ts')\n console.log(' ✓ Navigation updated')\n\n // Generate cache module (tags, cached-queries, revalidate)\n console.log('1️⃣2️⃣ Generating cache module...')\n const cacheFiles = await generateCache(schema, options)\n generatedFiles.push(...cacheFiles)\n console.log(' ✓ Cache module generated')\n\n // Success summary\n console.log('\\n✅ Generation complete!\\n')\n console.log('📁 Generated files:')\n for (const file of generatedFiles) {\n console.log(` - ${file}`)\n }\n\n // Run database migrations if not skipped\n if (!options.skipMigration) {\n console.log('\\n🗄️ Running database migrations...')\n\n // Check if DATABASE_URL is configured\n if (!process.env.DATABASE_URL) {\n console.warn('\\n⚠️ DATABASE_URL environment variable not found')\n console.warn(' Skipping database migration')\n console.warn(' To run migrations later:')\n console.warn(' 1. Configure DATABASE_URL in your .env file')\n console.warn(' 2. Run: pnpm db:push')\n } else {\n try {\n execSync('pnpm db:push', {\n cwd: paths.root,\n stdio: 'inherit'\n })\n console.log('\\n ✓ Database schema synced')\n } catch (error) {\n console.error('\\n⚠️ Database migration failed')\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n // Check for common migration errors and provide helpful guidance\n if (errorMessage.includes('value too long for type character varying')) {\n console.error(\n '\\n 💡 This error occurs when existing data exceeds varchar(255) limits.'\n )\n console.error(' Solution: Run a migration to alter columns to TEXT type:')\n console.error(' 1. Create a migration file in packages/database/drizzle/')\n console.error(' 2. Add: ALTER TABLE \"TableName\" ALTER COLUMN \"columnName\" TYPE text;')\n console.error(' 3. Run: pnpm db:migrate')\n console.error(' Or manually run the ALTER TABLE command in your database.')\n } else {\n console.error(' You can run manually: pnpm db:push')\n }\n console.error(` Error: ${errorMessage}`)\n }\n }\n }\n\n // Run linter and formatter as final step\n console.log('\\n🎨 Running formatter and linter...')\n try {\n execSync('pnpm lint:fix', {\n cwd: paths.root,\n stdio: 'pipe'\n })\n console.log(' ✓ Code formatted and linted with Biome')\n } catch (_error) {\n console.warn(' ⚠️ Linter encountered issues (this is usually fine)')\n console.warn(' You can run: pnpm lint:fix manually if needed')\n }\n\n console.log('\\n📝 Next steps:')\n console.log(' 1. Review the generated files')\n if (options.skipMigration) {\n console.log(' 2. Run migrations: pnpm db:push')\n console.log(` 3. Start the dev server and visit /admin/${schema.name}`)\n } else {\n console.log(` 2. Start the dev server and visit /admin/${schema.name}`)\n }\n console.log('')\n } catch (error) {\n console.error('\\n❌ Generation failed:', error)\n process.exit(1)\n }\n}\n"],"mappings":"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","names":["relationshipFields","hasRelationships","path","fs","path","fs","path","fs","path","path","fs","fs","path","path","fs","fs","path","getManyToManyFields","path","fs","fs","path","path","fs","fs","path","flattenFields","path","fs","fs","path","base","toPascalCase","path","fs","options","wrapWithShowWhen","stringLikeTypes","fs","path","hasDynamicFields","getAllFields","flattenFields","path","fs","fs","path","fs","path","path","fs","hasDynamicFields","getAllFields","flattenFields","getAllFields","hasDynamicFields","path","fs","match","generateForm","execSync","fs","path","path","fs","fs","path","parseNavigationFile","parseNavigationItem","parseSubItems","generateNavigationCode","path","fs","fs","path","path","fs","fs","path","path","fs","fs","path","path","fs","writeFileSync","resolve","resolve","writeFileSync","fs","path","path","fs"]}