Docs/cliv1.0.0-rc.1

udiot generate

Overview

udiot generate (alias g) scaffolds a component, service, controller, event or handler. The generated code imports the framework from @tagna/udiot and compiles in a TypeScript project that uses "module": "NodeNext" and "experimentalDecorators": true (relative imports end in .js). Output paths come from framework.conventions in udiot.config.json; without that file the defaults below apply.

Command

udiot generate <type> <name> [options]
udiot g <type> <name> [options]
Flag Description
-d, --dry-run List the files that would be written; write nothing
-y, --yes Write without asking for confirmation
-f, --force Overwrite files that already exist
--with-tests Also write a Jest test next to each file
--description <text> Doc comment for the generated class (events: their description)
--event-name <name> Event name, e.g. user.created (events and handlers)
--event-category <category> domain, system or ai (events; default domain)
--event-version <n> Event version (default 1)
--event-docs Also write a Markdown page for the event
--for-event <name> Event a handler subscribes to

Without --yes or --dry-run, the command lists the files and asks before writing them. A shell that cannot answer (CI, a pipe) gets an error asking for --yes instead. Existing files are never overwritten without --force.

What each type writes

Type Default path Contents
component src/components/<kebab-name>.ts BaseComponent subclass with @ComponentDecorator({ selector }), a props interface, onInit() and render()
service src/services/<kebab-name>.service.ts @Injectable() class with findAll, findOne, create, update and delete stubs
controller src/controllers/<kebab-name>.controller.ts @Controller('/<kebab-name>') with CRUD routes that call the matching service
event src/events/<kebab-name>.event.ts Payload interface and an @AIEventDefinition class
handler src/events/handlers/<kebab-name>.handler.ts @AIEventHandler class whose handle() receives the event

Names are PascalCase. A trailing Service, Controller, Event or Handler is optional: generate service OrderService and generate service Order both write OrderService to order.service.ts.

--with-tests writes <file>.test.ts beside the file. Tests import from @jest/globals; they check that the class can be created and that its public methods exist, and are a starting point for real tests.

Examples

# Preview
udiot generate component ProductCard --dry-run

# A service, its controller and tests, without prompts
udiot generate service Product --with-tests --yes
udiot generate controller Product --with-tests --yes

# An event and a handler for it
udiot generate event OrderPlaced --event-name order.placed --event-docs --yes
udiot generate handler NotifyWarehouse --for-event order.placed --yes

A controller imports the service of the same name (../services/product.service.js with the default paths), so generate the service too. A handler imports the payload type from the event file named after its event: handlers for order.placed import OrderPlacedPayload from order-placed.event.ts in the events directory. When an event is generated without --event-name, its name is derived from the class name (OrderPlaced → order.placed).

Integration notes

  • Paths, the file extension and the naming convention come from framework.conventions (componentPath, servicePath, controllerPath, eventPath, eventHandlerPath, eventDocsPath, fileExtension, namingConvention). Run udiot init to write a config with the defaults.
  • Generated stubs return placeholder values and carry TODO comments. Add validation, authorization and persistence before using them.
  • The controller's routes take Record<string, unknown> bodies; replace them with DTO classes when you add validation.
From the canonical UDIOT public documentation.Try it in the playground ↗