feat(dx): gen:context generator (WP-44)
npm run gen:context scaffolds a bounded context: folders + starter page, the @<ctx>/* tsconfig alias, a dependency-cruiser boundary entry, and a lazy authGuard route. Refactors .dependency-cruiser.js's per-context contextRule calls into a single CONTEXT_ALLOWED map that every rule derives from, so adding a context is really one config entry (verified behavior-preserving: same dep:check counts, same graph output). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+74
-1
@@ -6,7 +6,8 @@
|
||||
* Generators here are the pure-TS patterns (no Angular-template escaping): value objects and
|
||||
* form/wizard state machines. The UI-component and bff-endpoint patterns stay skill-driven —
|
||||
* they span the template `{{ }}` syntax / the C# backend + `gen:api` regen, where a generator
|
||||
* adds little over the recipe.
|
||||
* adds little over the recipe. `context` (WP-44) mechanises the `new-context` skill's manual
|
||||
* multi-file edit: folders + tsconfig alias + boundary entry + lazy route.
|
||||
*
|
||||
* Positional args skip the prompts, e.g. `npx plop value-object registratie KvkNummer`.
|
||||
*/
|
||||
@@ -60,4 +61,76 @@ export default function (plop) {
|
||||
remindEnXlf,
|
||||
],
|
||||
});
|
||||
|
||||
plop.setGenerator('context', {
|
||||
description:
|
||||
'Scaffold a bounded context: folders + tsconfig alias + boundary entry + lazy route',
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: 'Context name (lowercase, single Dutch ubiquitous term, e.g. vergunning):',
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/{{kebabCase name}}/ui/{{kebabCase name}}.page.ts',
|
||||
templateFile: 'plop-templates/context.page.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/{{kebabCase name}}/domain/.gitkeep',
|
||||
templateFile: 'plop-templates/gitkeep.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/{{kebabCase name}}/application/.gitkeep',
|
||||
templateFile: 'plop-templates/gitkeep.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/{{kebabCase name}}/infrastructure/.gitkeep',
|
||||
templateFile: 'plop-templates/gitkeep.hbs',
|
||||
},
|
||||
{
|
||||
type: 'add',
|
||||
path: 'src/app/{{kebabCase name}}/contracts/.gitkeep',
|
||||
templateFile: 'plop-templates/gitkeep.hbs',
|
||||
},
|
||||
{
|
||||
// tsconfig path alias — inserted right after the `"paths": {` line so it's stable
|
||||
// across repeated runs regardless of what's already been added.
|
||||
type: 'modify',
|
||||
path: 'tsconfig.json',
|
||||
pattern: /"paths": \{\n/,
|
||||
template: '"paths": {\n "@{{kebabCase name}}/*": ["src/app/{{kebabCase name}}/*"],\n',
|
||||
},
|
||||
{
|
||||
// Boundary entry (WP-38's single source of truth) — inserted right before the
|
||||
// `showcase: null` line, which never moves.
|
||||
type: 'modify',
|
||||
path: '.dependency-cruiser.js',
|
||||
pattern: /(\s*)showcase: null,/,
|
||||
template: "$1'{{kebabCase name}}': [],$1showcase: null,",
|
||||
},
|
||||
{
|
||||
// Lazy route — inserted right before the catch-all, which never moves.
|
||||
type: 'modify',
|
||||
path: 'src/app/app.routes.ts',
|
||||
pattern: " { path: '**', redirectTo: 'login' },",
|
||||
template: ` {
|
||||
path: '{{kebabCase name}}',
|
||||
canActivate: [authGuard],
|
||||
loadComponent: () =>
|
||||
import('@{{kebabCase name}}/ui/{{kebabCase name}}.page').then(
|
||||
(m) => m.{{pascalCase name}}Page,
|
||||
),
|
||||
},
|
||||
{ path: '**', redirectTo: 'login' },`,
|
||||
},
|
||||
() =>
|
||||
'Next: npm run dep:check && npm run lint && npm run build to verify, then build the first feature with the new-feature skill.',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user