Skip to content

Conversation

@gonengar
Copy link
Contributor

@gonengar gonengar commented Jan 24, 2026

Closes #101

Overview

This PR introduces the base44 types command - a TypeScript type generator that reads local entity schemas and produces fully-typed interfaces for use with the @base44/sdk.

Motivation

When building applications with Base44, developers define data models (entities) as JSON schema files:

// base44/entities/task.jsonc
{
  "name": "Task",
  "properties": {
    "title": { "type": "string" },
    "completed": { "type": "boolean" }
  },
  "required": ["title"]
}

However, when using these entities in TypeScript code via the SDK, there's no type safety:

// ❌ Before: No type safety
const base44 = createClient({ appId: 'my-app' });
const tasks = await base44.entities.Task.list();  // tasks: any
await base44.entities.Task.create({ titel: 'typo' });  // No error!

This PR solves that problem by generating TypeScript types from the schema files.

Solution

Command

base44 types [options]
 
Options:
  -o, --output <dir>  Output directory (default: "src/base44")
  --entities-only     Only generate entity types, skip client types

Generated Output

For each entity, the command generates:

Type Purpose
{Entity} Full entity interface with system fields (id, created_date, updated_date)
{Entity}CreateInput Input type for create operations (required fields enforced)
{Entity}UpdateInput Input type for updates (all fields optional)
{Entity}Filter Query filter type for list/filter operations

Plus SDK integration types:

  • EntityHandler<T> - Generic CRUD interface matching SDK methods
  • TypedEntities - Map of all entities to their handlers
  • TypedBase44Client - Drop-in typed wrapper for the SDK client

Example Output

Input: base44/entities/task.jsonc

{
  "name": "Task",
  "type": "object",
  "properties": {
    "title": { "type": "string", "description": "Task title" },
    "completed": { "type": "boolean", "default": false },
    "priority": { "type": "string", "enum": ["low", "medium", "high"] }
  },
  "required": ["title"]
}

Output: src/base44/entities.ts

export interface Task extends BaseEntity {
  /** Task title */
  title: string;
  completed?: boolean;
  priority?: 'low' | 'medium' | 'high';
}
 
export interface TaskCreateInput {
  title: string;  // Required
  completed?: boolean;
  priority?: 'low' | 'medium' | 'high';
}
 
export interface TaskUpdateInput {
  title?: string;  // All optional for partial updates
  completed?: boolean;
  priority?: 'low' | 'medium' | 'high';
}

Output: src/base44/client.ts

export interface TypedEntities {
  Task: EntityHandler<Task, TaskCreateInput, TaskUpdateInput, TaskFilter>;
}
 
export interface TypedBase44Client {
  entities: TypedEntities;
}

User Experience

Before (no types)

const base44 = createClient({ appId: 'my-app' });
 
// No autocomplete, no type checking
const tasks = await base44.entities.Task.list();
await base44.entities.Task.create({ titel: 'typo' });  // Typo not caught!

After (with generated types)

import { createClient } from '@base44/sdk';
import type { TypedBase44Client } from './base44/client';
 
const base44 = createClient({ appId: 'my-app' }) as TypedBase44Client;
 
// ✅ Full autocomplete on entity names
const { items } = await base44.entities.Task.list();
 
// ✅ items is typed as Task[]
items.forEach(task => console.log(task.title));
 
// ✅ Create input validates required fields
await base44.entities.Task.create({
  title: 'Buy groceries',  // Required - enforced
  priority: 'high'         // Autocomplete shows: 'low' | 'medium' | 'high'
});
 
// ❌ Compile error: 'titel' does not exist, did you mean 'title'?
await base44.entities.Task.create({ titel: 'typo' });
 
// ❌ Compile error: 'Orders' does not exist on TypedEntities
await base44.entities.Orders.list();

Implementation Details

Architecture

src/core/generate/
├── schema.ts      # Zod schemas for entity validation
├── generator.ts   # TypeScript code generation logic
├── types.ts       # Main generateTypes() orchestrator
└── index.ts       # Public exports
 
src/cli/commands/types/
└── generate.ts    # CLI command definition

Supported Field Types

JSON Schema Type TypeScript Output
string string
number number
boolean boolean
array T[] (with typed items)
object Inline object type or Record<string, unknown>
enum Union type: 'a' | 'b' | 'c'

Design Decisions

  1. Loose schema validation - Uses permissive Zod parsing to handle various JSON Schema extensions
  2. Separate files - Entities and client types in separate files for flexibility
  3. No runtime dependency - Generated code is pure TypeScript interfaces (type-only)
  4. SDK-compatible - EntityHandler interface matches @base44/sdk method signatures exactly

Testing

# Tested with fixture projects
cd tests/fixtures/with-entities
base44 types
 
# Verified output compiles
npx tsc --noEmit src/base44/*.ts

Documentation

  • Updated README.md with:
    • Command reference in commands table
    • Dedicated "TypeScript Type Generation" section
    • Setup instructions for tsconfig.json
    • Usage examples with @base44/sdk
    • Updated project structure diagram

Future Improvements

  • Module augmentation approach (no casting needed)
  • Zod runtime validators alongside TypeScript types

Generates TypeScript types from local entity schemas:
- Entity interfaces with system fields (id, created_date, updated_date)
- CreateInput/UpdateInput types for CRUD operations
- Filter types for query operations
- Typed SDK client interface matching @base44/sdk API

Usage: base44 generate [-o <dir>] [--entities-only]
- base44 generate → base44 types
- Update generated file header comments
- Document the types command and its options
- Add TypeScript type generation section with usage examples
- Update project structure to show generated types directory
@github-actions
Copy link
Contributor

github-actions bot commented Jan 24, 2026

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/cli@0.0.15-pr.102.ec2ad29

Prefer not to change any import paths? Install using npm alias so your code still imports base44:

npm i "base44@npm:@base44-preview/cli@0.0.15-pr.102.ec2ad29"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "base44": "npm:@base44-preview/cli@0.0.15-pr.102.ec2ad29"
  }
}

Preview published to npm registry — try new features instantly!

@gonengar gonengar changed the title feat: Add base44 generate command for TypeScript type generation feat: Add base44 types command for TypeScript type generation Jan 24, 2026
Consistent naming with the `base44 types` command.
- Add support for `integer` type (maps to `number`)
- Add support for `null` type
- Add support for union types: `["string", "null"]` → `string | null`
- Support mixed enum values (string, number, boolean, null)
- Add `format` field support in schema
- Fix inline object generation for nested properties
Replace in-house JSON Schema → TypeScript conversion with the
battle-tested json-schema-to-typescript library.

Benefits:
- Full JSON Schema draft-07 support
- Handles $ref, allOf, anyOf, oneOf
- Proper JSDoc generation from descriptions
- Better handling of complex nested types
- Output types.d.ts for Node.js (declare module '@base44/sdk')
- Output types.deno.d.ts for Deno (declare module 'npm:@base44/sdk')
- Default output directory changed to base44/ (alongside entity schemas)
- User code remains unchanged - types are injected via module augmentation
- Add --node-only flag to skip Deno types generation
Document the full product specification including:
- Command usage and options
- Generated file structure for Node.js and Deno
- Setup instructions for tsconfig.json and deno.json
- User experience walkthrough with examples
- JSON Schema to TypeScript type mapping reference
- SDK requirements for module augmentation support
- Recommended workflow for type generation
@kfirstri
Copy link
Contributor

kfirstri commented Feb 2, 2026

Wokring on my own branch

@kfirstri kfirstri closed this Feb 2, 2026
@github-project-automation github-project-automation bot moved this from Backlog to Done in CLI Development Feb 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Feature]: Add base44 types command for TypeScript type generation

4 participants