irstea/ng-model-generator-bundle
A Symfony bundle that generates Angular/TypeScript model classes from Doctrine entities, helping keep frontend and backend data structures in sync. Automate model creation for API-driven Angular apps and reduce manual boilerplate.
Framework reality check before anything else: despite the vendor-neutral name, this is a Symfony bundle, not a Laravel package. It consumes API Platform resource metadata (Symfony DI, ResourceMetadataFactory, serializer property metadata) and emits Angular TypeScript models. There is no service provider, no Artisan command, no config publish. If your backend is Laravel, you cannot "just install" this — you either run it as a sidecar in a small Symfony app pointed at the same metadata, or treat the repo as a reference implementation of the "API-metadata → TS models" pattern and drive your own generator from an OpenAPI export.
Minimal steps in a Symfony + API Platform host:
gitlab.irstea.fr, not Packagist), then composer require irstea/ng-model-generator-bundle. Pin to a commit SHA — assume no tags and no semver.config/bundles.php:
Irstea\NgModelGeneratorBundle\NgModelGeneratorBundle::class => ['all' => true],
Verify after composer require — private bundles almost never ship a Flex recipe, so this is usually manual.src/Command/ — commonly something like ng-model:generate; confirm, don't guess).Where to look first, in order:
README.md / description.md for the command name and config keys — then cross-check against code, private-bundle docs go stale.src/Command/ — the entry point. This tells you exactly what it reads (metadata) and writes (files, where).src/DependencyInjection/Configuration.php — the authoritative config tree: output path, resource filters, template options. Trust this over docs.Resources/ or templates/ — the templates shaping the emitted .ts. This is where the actual TypeScript conventions live.First use case to validate: pick one representative entity — a few scalars, one relation, one nullable field, one enum. Run the generator, open the emitted .ts, and confirm it compiles under your Angular strict settings. Do this before wiring anything into CI or a second entity. You are validating output quality, not just "it ran."
Config-driven mapping is the main lever. The bundle is a mapping engine: Doctrine/API Platform metadata on one side, TypeScript type conversion on the other. Do the type work in config and templates, not in post-processing scripts — that keeps the mapping reviewable and re-runnable.
interface vs class, readonly fields, enums as const enum or string unions, dates as string vs Date. This is the cleanest extension point and avoids patching generator internals.gitignore or commit deliberately — pick one, don't drift. Hand-edits get silently clobbered on the next run.The regeneration workflow that actually holds up:
git diff --exit-code. If metadata changed and models didn't, the pipeline fails and the schema change surfaces in code review instead of in production.Sidecar pattern (Laravel or non-Symfony host). Run a minimal Symfony app containing the bundle against the same API Platform metadata, emit .ts into the Angular repo as a CI artifact. Keeps the host app untouched, preserves the original design's fidelity, at the cost of a second deployable and version-skew risk (see below).
Integration tip: wrap the raw command behind your own thin script so the invocation, config path, and output dir are fixed in one place. When (not if) you fork the emitter, that wrapper is the swap point — the calling code and CI don't change.
NgModelGeneratorServiceProvider exists. Confirm Symfony + API Platform before spending an hour on install.gitlab.irstea.fr may require auth or be unreachable from CI. Mirror the repo internally and pin a SHA. Set "minimum-stability" / prefer-stable appropriately for an untagged VCS dependency.readOnly. Generated optional fields must map to ?: / | null correctly, or you get runtime undefined in Angular that strict mode won't catch at the boundary. Add these cases to your first-use-case validation.Bottom line for a Laravel developer: this is not a dependency you adopt; it's a pattern to learn from. Default to openapi-typescript/orval on an exported OpenAPI spec — maintained, framework-agnostic, and covers more than models. Reach for this bundle only on a genuine Symfony + API Platform + Angular stack, with a named internal owner and a documented exit path.
How can I help you explore Laravel packages today?