ThlsPressThlsPress
CLI Tools

Creating Modules

Guide to creating new modules for THLSPress

Guide: Creating a New Module

This guide provides a comprehensive walkthrough for developers on how to create a new, installable module for the THLSPress ecosystem. Adhering to this structure ensures compatibility with the thlspress-cli.

A module is a self-contained directory located in the /templates folder of the monorepo.

1. Module Structure

Every module must follow a specific directory structure. Let's use a hypothetical store module as an example:

templates/
└── store/
    ├── app/
    │   ├── (auth-routes)/admin-panel/store/
    │   │   ├── products/
    │   │   └── orders/
    │   ├── (pages)/store/
    │   └── api/store/
    ├── codemods/
    │   └── sidebar.snippet.ts
    ├── prisma/
    │   ├── append.prisma.snippet
    │   └── inject.prisma.snippet
    └── module.json
  • module.json (Required): The manifest file that defines the module.
  • app/ (Required): Contains the Next.js application code. The CLI will merge this directory with the user's project app/ directory.
  • prisma/ (Optional): Contains snippets for modifying the database schema.
  • codemods/ (Optional): Contains snippets for modifying existing TypeScript/JavaScript files.

2. The module.json Manifest

This JSON file is the heart of your module. It provides the CLI with all the necessary metadata.

Example templates/store/module.json:

{
  "name": "store",
  "version": "1.0.0",
  "description": "Adds a fully-featured e-commerce platform to THLSPress.",
  "dependencies": {
    "stripe": "15.8.0",
    "zod": "3.23.8"
  },
  "devDependencies": {}
}
  • name: The unique, kebab-case identifier for the module.
  • version: The semantic version of the module.
  • dependencies: A map of production dependencies and their exact versions required by the module.
  • devDependencies: A map of development dependencies.

3. Modifying the Database (/prisma)

If your module requires database changes, you must provide snippets in the /prisma directory.

  • append.prisma.snippet:

    • Purpose: To add brand new, self-contained models and enums.
    • Content: Contains full Prisma model definitions (e.g., model Product { ... }, model Order { ... }).
    • Convention: Wrap the entire content in // --- START <MODULE_NAME> MODULE --- and // --- END <MODULE_NAME> MODULE --- comments to prevent duplicate injection.
  • inject.prisma.snippet:

    • Purpose: To add fields or relations to existing core models.
    • Content: Uses a special syntax with // @@TARGET: blocks to specify where to inject code.

    Example inject.prisma.snippet:

    // Add a relation to the core User model for their orders.
    // @@TARGET: USER
    orders Order[]

4. Modifying Source Code (/codemods)

To modify existing files like the admin panel sidebar, use the /codemods directory.

  • File Naming: Snippets should be named descriptively (e.g., sidebar.snippet.ts, tailwind.config.snippet.js).

  • Snippet Syntax: A snippet file has two parts: an optional import section and one or more target sections.

    Example sidebar.snippet.ts:

    // Defines required imports for the code below.
    // Format: <package-name>: <Import1>, <Import2>
    // @@IMPORTS
    // lucide-react: ShoppingCart, Package
    
    // Defines the code block to be injected.
    // @@TARGET: SIDEBAR_ROOT
    {
      type: "collapsible",
      label: "Store",
      icon: ShoppingCart,
      children: [
        {
          type: "sublink",
          label: "Products",
          href: "/admin-panel/store/products",
          icon: Package,
        },
      ],
    },
  • Target File Preparation: The target file in the Core CMS (e.g., cms/components/Sidebar/defaultSidebarItems.ts) must be prepared with corresponding markers:

    • // THLSPRESS:INJECT:IMPORTS for new import statements.
    • // THLSPRESS:INJECT:LUCIDE_IMPORTS specifically for lucide-react imports.
    • // THLSPRESS:INJECT:SIDEBAR_ROOT for the code block itself.

By following this guide, you can create powerful, reusable modules that seamlessly integrate with the THLSPress ecosystem.