Skip to content

Add configurable add-on options system with Prisma ORM #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

timoconnellaus
Copy link
Collaborator

@timoconnellaus timoconnellaus commented Jul 3, 2025

Summary

This PR implements a comprehensive add-on options system that allows add-ons to define configurable options for users during app creation.

What This Enables

  • Database provider selection - Choose between PostgreSQL, MySQL, or SQLite for Prisma ORM
  • Interactive UI configuration - Configure add-on options through a clean dialog interface
  • Framework-specific configurations - Tailor add-ons to different setups and preferences
  • Dynamic dependencies - Install only the packages needed for chosen options
  • Automated workflows - Configure add-ons non-interactively via JSON

Template Configuration Examples

Add-on definition with options:

{
  "name": "Prisma ORM",
  "options": {
    "database": {
      "type": "select",
      "label": "Database Provider",
      "default": "postgres",
      "options": [
        { "value": "postgres", "label": "PostgreSQL" },
        { "value": "mysql", "label": "MySQL" },
        { "value": "sqlite", "label": "SQLite" }
      ]
    }
  }
}

Conditional file generation based on options:

<\!-- __postgres__schema.prisma.ejs -->
<% if (addOnOption.prisma.database \!== 'postgres') { ignoreFile() } %>
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Dynamic package dependencies:

{
  "dependencies": {
    "prisma": "^5.8.0",
    "@prisma/client": "^5.8.0",
    <% if (addOnOption.prisma.database === 'postgres') { %>
    "pg": "^8.11.0",
    <% } %>
    <% if (addOnOption.prisma.database === 'mysql') { %>
    "mysql2": "^3.6.0",
    <% } %>
  },
  "devDependencies": {
    <% if (addOnOption.prisma.database === 'postgres') { %>
    "@types/pg": "^8.10.0"
    <% } %>
    <% if (addOnOption.prisma.database === 'mysql') { %>
    "@types/mysql2": "^3.6.0"
    <% } %>
    <% if (addOnOption.prisma.database === 'sqlite') { %>
    "@types/better-sqlite3": "^7.6.0"
    <% } %>
  }
}

Key Features Implemented

  • Configurable add-on options with Zod schema validation
  • EJS template integration with addOnOption context variable
  • Conditional file generation using __prefix__ filename patterns
  • Dynamic package dependencies via package.json.ejs templates
  • Complete CLI integration with discovery and configuration features
  • Interactive UI with dialog-based configuration system
  • Non-interactive automation support via JSON configuration

CLI Usage Examples

# Discovery workflow
node cli/create-tsrouter-app/dist/index.js --list-add-ons
node cli/create-tsrouter-app/dist/index.js --addon-details prisma

# Interactive configuration
node cli/create-tsrouter-app/dist/index.js my-app --add-ons prisma

# Non-interactive automation
node cli/create-tsrouter-app/dist/index.js my-app --add-ons prisma --add-on-config '"'"'{"prisma":{"database":"mysql"}}'"'"'

Test plan

  • Add-on options schema validation works correctly
  • Conditional file generation based on database selection
  • Dynamic package dependencies installation
  • CLI discovery and configuration workflows
  • Interactive UI configuration dialog
  • Non-interactive automation via JSON config
  • Prisma ORM integration with PostgreSQL, MySQL, and SQLite
  • TanStack Router integration with proper route structure
  • Server functions integration with TanStack Start

- Add Zod schemas for add-on option definitions
- Support conditional file generation with EJS templates
- Enable package.json.ejs for conditional dependencies
- Implement filename prefix stripping for database-specific files
- Create Drizzle add-on with database provider option
- Move add-on configuration from inline display to dedicated dialog
- Add settings button (gear icon) next to info icon for configurable add-ons
- Create new AddOnConfigDialog component with proper modal interface
- Fix reactive state subscription for add-on options in sidebar
- Clean up sidebar layout by removing inline configuration clutter
- Add proper default option initialization when add-ons are toggled
- Export add-on option types from engine for better type safety

Improves UX by providing dedicated space for configuration with clear
context while keeping the sidebar clean and compact.
- Enhanced --list-add-ons to show * for configurable add-ons
- Added --addon-details command to show comprehensive add-on information
- Added --add-on-config option for non-interactive configuration
- Supports discovering options, dependencies, routes, and all add-on metadata
Implements Phase 4 testing for the add-on options system with comprehensive unit test coverage:

- add-on-options.test.ts: Zod schema validation, default population, and error handling (15 tests)
- template-context.test.ts: EJS template context with addOnOption variable integration (12 tests)
- filename-processing.test.ts: Prefix stripping logic for __prefix__filename patterns (11 tests)
- conditional-packages.test.ts: EJS conditional package.json processing (11 tests)

Key test coverage areas:
- Option schema validation with comprehensive positive/negative cases
- Template variable integration and conditional file processing
- Filename prefix stripping (__option__filename.ext.ejs → filename.ext)
- Conditional package dependency generation via EJS templates
- Error handling for malformed options and templates

All 49 new tests pass, ensuring robust validation of the add-on options functionality.
@timoconnellaus timoconnellaus changed the title WIP: Add configurable add-on options system Add configurable add-on options system Jul 3, 2025
- Document configuration format and option types in info.json
- Explain template usage with addOnOption variables
- Cover conditional file naming conventions with prefixes
- Provide complete examples for both React CRA and Solid frameworks
- Include CLI usage patterns for interactive and non-interactive modes
- Add best practices for add-on developers
@timoconnellaus timoconnellaus changed the title Add configurable add-on options system Add configurable add-on options system with Prisma ORM Jul 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant