/**
* cli:scaffold-extension-config — generate.ts
*
* Emits an ExtensionConfig for a module, listing every slot that the scaffolded
* components publish via ``. Clients (or other extensions)
* fill these slots with ``.
*
* ExtensionConfig type comes from `@atlashub/smartstack` (npm).
*
* The slot catalog below mirrors the exact `` calls emitted by
* `frontend/component` generator. Renaming slots in one place without the other
* breaks composition silently.
*/
import type { ScaffoldExtensionConfigInput, GeneratedFile } from './types.js'
interface SlotDescriptor {
name: string
description: string
contextShape: string
}
function buildSlots(module: string, entity: string): SlotDescriptor[] {
const eLower = entity.charAt(0).toLowerCase() + entity.slice(1)
const base = `${module}.${eLower}`
return [
{ name: `${base}.list.before`, description: `Rendered above the ${entity} list table.`, contextShape: `{}` },
{ name: `${base}.list.after`, description: `Rendered below the ${entity} list table.`, contextShape: `{}` },
{ name: `${base}.detail.before`, description: `Rendered at the top of the ${entity} detail page.`, contextShape: `{ data: ${entity} }` },
{ name: `${base}.detail.after`, description: `Rendered at the bottom of the ${entity} detail page.`, contextShape: `{ data: ${entity} }` },
{ name: `${base}.form.fields.before`, description: `Injects form fields before the scaffolded ones.`, contextShape: `{ formData: ${entity}FormData, onChange: (field, value) => void }` },
{ name: `${base}.form.fields.after`, description: `Injects form fields after the scaffolded ones.`, contextShape: `{ formData: ${entity}FormData, onChange: (field, value) => void }` },
]
}
export function generate(spec: ScaffoldExtensionConfigInput): GeneratedFile[] {
const allSlots = spec.entities.flatMap(e => buildSlots(spec.module, e))
const jsDocLines = allSlots
.map(s => ` * - '${s.name}': ${s.description}\n * context: ${s.contextShape}`)
.join('\n')
const slotEntries = allSlots.map(s => ` '${s.name}': null,`).join('\n')
const content = `import type { ExtensionConfig } from '@atlashub/smartstack';
/**
* Extension configuration for the ${spec.module} module.
*
* Slot catalog (each call below must match exactly):
${jsDocLines}
*
* Add Fill components in your app entrypoint to inject content into any slot:
* {yourJsx}
*/
export const ${spec.module}Config: ExtensionConfig = {
slots: {
${slotEntries}
},
tableColumns: {},
formFields: {},
hooks: {},
};
`
return [{ path: `src/extensions/${spec.module}Extensions.ts`, content }]
}