Laravel Module Generator

v 1.3.*

🛠️ Module generation (from YAML)

This package generates a complete API module (Model, Migration, Controller, Service, Resource, Collection, Form Request, routes, and optional Postman / DBML artifacts) from a single YAML file. The default configuration file path is module/models.yaml.

YAML file location

  • Default: module/models.yaml
  • You can pass a custom file to the CLI with --file=path/to/file.yaml.

Minimal example (quick)

Product:
  fields:
    name: string:unique
    code: string:unique
    description: text:nullable
    is_active: boolean:default true
  relations:
    belongsTo: User:creator

Full example (more features)

User:
  generate_only: seeder
  fields:
    name: string
    email: string:unique
    email_verified_at: dateTime:nullable
    password: string
    avatar: image:nullable
    status: boolean:default true
    last_login_at: timestamp:nullable

Category:
  generate_except: seeder
  fields:
    name: string:unique
    slug: string:unique
    description: text:nullable
    image: image:nullable
    parent_id: foreignId:categories:nullable
    is_active: boolean:default true
    display_order: integer:default 0
    seo_title: string:nullable
    seo_description: string:nullable
    seo_keywords: string:nullable
    created_by: foreignId:users:nullable
    updated_by: foreignId:users:nullable
  relations:
    belongsTo: Category:parent, User:creator, User:updater
    hasMany: Category:children, Product:products
  nested_requests: children

Product:
  generate: all
  fields:
    vendor_id: foreignId:vendors:nullable
    category_id: foreignId:categories
    brand_id: foreignId:brands:nullable
    name: string
    slug: string:unique
    sku: string:unique
    description: text:nullable
    short_description: string:nullable
    price: double:default 0
    cost_price: double:default 0
    compare_price: double:default 0
    quantity: integer:default 0
    is_active: boolean:default true
    is_featured: boolean:default false
    rating: double:default 0
    total_reviews: integer:default 0
    weight: double:nullable
    dimensions: string:nullable
    seo_title: string:nullable
    seo_description: string:nullable
    seo_keywords: string:nullable
    meta_data: json:nullable
    created_by: foreignId:users:nullable
    updated_by: foreignId:users:nullable
    deleted_at: dateTime:nullable
  relations:
    belongsTo: Vendor, Category, Brand, User:creator, User:updater
    hasMany: Review, ProductVariant:variants, ProductImage:images
    belongsToMany: ProductAttribute
  nested_requests: variants, images

ProductImage:
  generate_only: model, migration, seeder, service
  fields:
    product_id: foreignId:products
    image_url: image
    alt_text: string:nullable
    display_order: integer:default 0
    is_thumbnail: boolean:default false
    created_by: foreignId:users:nullable
    updated_by: foreignId:users:nullable
  relations:
    belongsTo: Product, User:creator, User:updater

ProductVariant:
  generate: all
  fields:
    product_id: foreignId:products
    sku: string:unique
    name: string
    price: double:nullable
    cost_price: double:nullable
    quantity: integer:default 0
    attributes_data: json:nullable
    image_id: foreignId:product_images:nullable
    is_active: boolean:default true
    created_by: foreignId:users:nullable
    updated_by: foreignId:users:nullable
  relations:
    belongsTo: Product, ProductImage:image, User:creator, User:updater

ProductAttributeValue:
  generate: all
  fields:
    attribute_id: foreignId:product_attributes
    value: string
    slug: string
    display_order: integer:default 0
    created_by: foreignId:users:nullable
    updated_by: foreignId:users:nullable
  relations:
    belongsTo: ProductAttribute:attribute, User:creator, User:updater
  unique:
    - [product_attribute_id, value]

YAML schema reference (comprehensive guide)

Top-level structure

Each model is defined as a top-level key in PascalCase (e.g., Product, User, Category). Under each model, you can specify:

Model properties

generate (optional)

Generate all the components or the specified components.

User:
  generate: all  # Generate everything
  # OR
  generate: model, migration, seeder, controller, service, request, resource, collection # Generates only specified components

generate_only (optional)

Generate ONLY the specified components. All other components will be skipped.

User:
  generate_only: seeder  # Only generate seeder
  # OR
  generate_only: model, migration  # Only generate model and migration

generate_except (optional)

Generate all components EXCEPT the specified ones.

Product:
  generate_except: seeder  # Generate everything except seeder
  # OR
  generate_except: controller, service  # Skip controller and service

Valid component names:

  • model
  • migration
  • controller
  • service
  • request
  • resource
  • collection
  • seeder

Note: If neither generate, generate_only or generate_except is not specified, no components are generated.

fields (required)

Map of field names to type definitions with optional modifiers.

Format: fieldName: type[:modifier[:modifier...]]

Supported field types:

  • String types: string, text, longText
  • Numeric types: integer, bigInteger, double, float, decimal
  • Boolean: boolean
  • Date/Time: date, dateTime, timestamp, time
  • File types: image, file (automatically handles file upload and validation)
  • JSON: json
  • Enum: enum
  • Foreign keys: foreignId:table_name (e.g., foreignId:users, foreignId:categories)
  • Soft deletes: Add deleted_at: dateTime:nullable to enable soft deletes

Common modifiers (chainable):

  • nullable — Column can be null
  • unique — Add unique constraint and validation
  • default <value> — Set default value (e.g., default true, default 0, default pending)

Examples:

fields:
  # Basic string
  name: string
  
  # String with unique constraint
  email: string:unique
  
  # Text field that's nullable
  description: text:nullable
  
  # Image field (nullable, enables file upload handling)
  avatar: image:nullable
  
  # Boolean with a default value
  is_active: boolean:default true
  status: boolean:default false
  
  # Numeric with default
  price: double:default 0
  quantity: integer:default 0
  
  # Foreign key (references users' table)
  user_id: foreignId:users
  
  # Foreign key with nullable
  parent_id: foreignId:categories:nullable
  
  # Foreign key with multiple modifiers
  created_by: foreignId:users:nullable
  
  # Unique string with nullable
  slug: string:unique:nullable
  
  # Date/time fields
  published_at: dateTime:nullable
  expires_at: dateTime:nullable
  
  # Soft deletes
  deleted_at: dateTime:nullable
  
  # JSON data
  meta_data: json:nullable
  settings: json
relations (optional)

Define model relationships using a compact format.

Format: relationType: Model:functionName, Model:functionName, ...

Supported relation types:

  • belongsTo — Many-to-one relationship
  • hasMany — One-to-many relationship
  • hasOne — One-to-one relationship
  • belongsToMany — Many-to-many relationship (requires pivot table)
  • morphTo, morphMany, morphOne — Polymorphic relationships

Compact relation format:

relations:
  # Simple belongsTo
  belongsTo: User
  
  # belongsTo with custom function name
  belongsTo: User:creator, User:updater # Model:relationName
  
  # Multiple relation types
  belongsTo: Category:parent, User:creator, User:updater
  hasMany: Category:children, Product:products
  hasOne: Profile
  
  # Self-referencing
  belongsTo: Category:parent
  hasMany: Category:children
  
  # Many-to-many
  belongsToMany: Tag, Category

Relation naming conventions:

  • If the function name is omitted, it defaults to the camelCase of the model name
  • Useruser()
  • User:creatorcreator() (references created_by foreign key)
  • User:updaterupdater() (references updated_by foreign key)
  • Category:parentparent() (references parent_id foreign key)
  • Category:childrenchildren() (inverse of parent)

Special relation names:

  • creator → Maps to created_by field
  • updater → Maps to updated_by field
  • parent → Maps to parent_id field
nested_requests (optional)

Specify which relations should be included in nested request bodies for Postman collection generation.

Product:
  relations:
    hasMany: ProductVariant:variants, ProductImage:images
  nested_requests: variants, images  # Include it in Postman nested requests

Notes:

  • Only works with hasMany and hasOne relations
  • Prevents circular reference issues with belongsTo
  • Generates nested request bodies in a Postman collection
unique (optional)

Define compound unique constraints (multiple columns together must be unique).

SocialLogin:
  fields:
    user_id: foreignId:users
    provider: string
  unique:
    - [user_id, provider]  # Combination must be unique

ProductAttributeValue:
  fields:
    attribute_id: foreignId:product_attributes
    value: string
  unique:
    - [attribute_id, value]  # Compound unique constraint