74 lines
3.2 KiB
TypeScript
74 lines
3.2 KiB
TypeScript
import { join } from 'node:path'
|
|
import { writeBackendModule } from '#services/module_generator/writers/backend_module_writer'
|
|
import DataTableSourceBuilder from '#services/module_generator/builders/data_table_source_builder'
|
|
import FormSourceBuilder from '#services/module_generator/builders/form_source_builder'
|
|
import ListPageSourceBuilder from '#services/module_generator/builders/list_page_source_builder'
|
|
import ManageTriggerSourceBuilder from '#services/module_generator/builders/manage_trigger_source_builder'
|
|
import MenuSourceBuilder from '#services/module_generator/builders/menu_source_builder'
|
|
import ModuleConfigSourceBuilder from '#services/module_generator/builders/module_config_source_builder'
|
|
import { writeFrontendModule } from '#services/module_generator/writers/frontend_module_writer'
|
|
import { buildModuleContext, ModuleContext } from '#services/module_generator/module_context'
|
|
import { capitalize } from '#services/module_generator/naming'
|
|
import { ModuleAsset, ModuleGeneratorConfig } from '#services/module_generator/types'
|
|
|
|
/**
|
|
* Generates a full module from its table schema and generator config:
|
|
* frontend module in the sibling admin workspace, backend assets under
|
|
* modules/<Module>. Returns the generated module's name.
|
|
*/
|
|
export async function generateModule(config: ModuleGeneratorConfig): Promise<string> {
|
|
const appBase = process.cwd()
|
|
const context = await buildModuleContext(config.table)
|
|
|
|
writeFrontendAssets(config, context, appBase)
|
|
await writeBackendModule({
|
|
name: config.name,
|
|
table: config.table,
|
|
generate: config.generate,
|
|
appBase,
|
|
context,
|
|
})
|
|
|
|
return capitalize(config.name)
|
|
}
|
|
|
|
// Template tree first (hbs rendered, the rest copied verbatim), then builder
|
|
// output for the selected assets. Files whose asset is not selected keep the
|
|
// scaffold defaults from the template tree.
|
|
function writeFrontendAssets(
|
|
config: ModuleGeneratorConfig,
|
|
context: ModuleContext,
|
|
appBase: string
|
|
) {
|
|
const { name, generate, form, datatable } = config
|
|
const shouldGenerateForm = generate.includes(ModuleAsset.FORM) && !!form
|
|
const shouldGenerateDataTable = generate.includes(ModuleAsset.DATATABLE) && !!datatable
|
|
|
|
writeFrontendModule({
|
|
templateDir: join(appBase, 'app', 'templates', 'frontend', 'module'),
|
|
outDir: join(appBase, '..', 'admin', 'src', 'modules', capitalize(name)),
|
|
context: { name, fields: context.frontendFields },
|
|
overrides: {
|
|
'view/forms/MainForm/Component.tsx': shouldGenerateForm
|
|
? FormSourceBuilder.buildComponent(form)
|
|
: null,
|
|
'view/forms/MainForm/form.ts': shouldGenerateForm
|
|
? FormSourceBuilder.buildDefinition(form)
|
|
: null,
|
|
'view/widgets/ManageTrigger.tsx': shouldGenerateForm
|
|
? ManageTriggerSourceBuilder.build(form.size)
|
|
: null,
|
|
'view/widgets/DataTable.tsx': shouldGenerateDataTable
|
|
? DataTableSourceBuilder.build(config)
|
|
: null,
|
|
'pages/ListPage/index.tsx': ListPageSourceBuilder.build({
|
|
addTable: shouldGenerateDataTable,
|
|
}),
|
|
'config/menu.ts': shouldGenerateDataTable ? MenuSourceBuilder.build() : null,
|
|
'config/module.ts': ModuleConfigSourceBuilder.build(name, {
|
|
includeMenu: shouldGenerateDataTable,
|
|
}),
|
|
},
|
|
})
|
|
}
|