Generate Zod schemas and TypeScript types from Directus collections automatically.
π For detailed installation tutorial, see INSTALLATION.md
# Install directly from GitHub
pnpm add https://github.com/InformationSystemsAgency/zodirectus.git
# Or install globally for CLI usage
pnpm add -g https://github.com/InformationSystemsAgency/zodirectus.gitGenerate schemas and types for all collections:
zodirectus --url https://your-directus-instance.com --token your-access-tokenGenerate for specific collections:
zodirectus --url https://your-directus-instance.com --token your-token --collections users,posts,commentsUsing email/password authentication:
zodirectus --url https://your-directus-instance.com --email [email protected] --password your-passwordimport { Zodirectus } from 'zodirectus';
const zodirectus = new Zodirectus({
directusUrl: 'https://your-directus-instance.com',
token: 'your-access-token',
outputDir: './generated',
generateTypes: true,
generateSchemas: true,
});
// Generate all schemas and types
const results = await zodirectus.generate();
// Generate for specific collections only
const zodirectusSpecific = new Zodirectus({
directusUrl: 'https://your-directus-instance.com',
token: 'your-access-token',
collections: ['users', 'posts'], // Only generate for these collections
outputDir: './generated',
});
const specificResults = await zodirectusSpecific.generate();| Option | Type | Default | Description |
|---|---|---|---|
directusUrl |
string | - | Required. Your Directus instance URL |
token |
string | - | Authentication token (alternative to email/password) |
email |
string | - | Email for authentication |
password |
string | - | Password for authentication |
collections |
string[] | - | Specific collections to generate (default: all) |
outputDir |
string | ./generated |
Output directory for generated files |
generateTypes |
boolean | true |
Generate TypeScript types |
generateSchemas |
boolean | true |
Generate Zod schemas |
includeSystemCollections |
boolean | false |
Include Directus system collections |
customFieldMappings |
object | {} |
Custom field type mappings |
zodirectus [options]
Options:
-u, --url <url> Directus instance URL (required)
-t, --token <token> Authentication token
-e, --email <email> Email for authentication
-p, --password <password> Password for authentication
-c, --collections <list> Comma-separated list of collections to generate
-o, --output <dir> Output directory (default: ./generated)
--schemas Generate Zod schemas (default: true)
--no-schemas Skip Zod schema generation
--types Generate TypeScript types (default: true)
--no-types Skip TypeScript type generation
--system Include system collections
-h, --help Show this help message
-v, --version Show version information
Examples:
zodirectus --url https://api.example.com --token your-token
zodirectus --url https://api.example.com --email [email protected] --password pass123
zodirectus --url https://api.example.com --collections users,posts --output ./typesZodirectus generates individual files for each collection in the output directory. Each file contains both Zod schemas and TypeScript types for that collection.
generated/
βββ user.ts
βββ post.ts
βββ comment.ts
βββ ...
Each collection file includes multiple Zod schemas:
// user.ts
import { z } from 'zod';
export const DrxUserSchema = z.object({
id: z.string().uuid().optional(),
email: z.string().email(),
first_name: z.string().nullable().optional(),
last_name: z.string().nullable().optional(),
role: z.string().nullable().optional(),
status: z.string().nullable().optional(),
date_created: z.string().datetime().nullable().optional(),
date_updated: z.string().datetime().nullable().optional(),
});
export const DrxUserCreateSchema = DrxUserSchema.omit({
id: true,
user_created: true,
date_created: true,
user_updated: true,
date_updated: true
});
export const DrxUserUpdateSchema = DrxUserSchema.partial().required({
id: true
});
export const DrxUserGetSchema = DrxUserSchema;Each collection file includes TypeScript interfaces using utility types:
// user.ts
export interface DrsUser {
id?: string;
email: string;
first_name?: string;
last_name?: string;
role?: string;
status?: string;
date_created?: string;
date_updated?: string;
}
export type DrsUserCreate = Omit<DrsUser, "id" | "user_created" | "date_created" | "user_updated" | "date_updated">;
export type DrsUserUpdate = Partial<DrsUser> & Required<Pick<DrsUser, "id">>;
export type DrsUserGet = DrsUser;Zodirectus uses consistent naming conventions for generated schemas and types:
- Base Schema:
Drx{CollectionName}Schema(e.g.,DrxUserSchema) - Create Schema:
Drx{CollectionName}CreateSchema(e.g.,DrxUserCreateSchema) - Update Schema:
Drx{CollectionName}UpdateSchema(e.g.,DrxUserUpdateSchema) - Get Schema:
Drx{CollectionName}GetSchema(e.g.,DrxUserGetSchema)
- Base Type:
Drs{CollectionName}(e.g.,DrsUser) - Create Type:
Drs{CollectionName}Create(e.g.,DrsUserCreate) - Update Type:
Drs{CollectionName}Update(e.g.,DrsUserUpdate) - Get Type:
Drs{CollectionName}Get(e.g.,DrsUserGet)
- Collection names are converted to kebab-case (e.g.,
user.ts,user-profile.ts)
- π Automatic Generation: Generate Zod schemas and TypeScript types from your Directus collections
- π― Type Safety: Full TypeScript support with proper type inference
- π CLI Tool: Easy-to-use command-line interface
- π¦ Library: Use as a library in your Node.js applications
- π§ Customizable: Support for custom field mappings and configurations
- ποΈ Build Ready: Generated files are ready for production use
- π Relations Support: Automatic handling of Directus relations (M2O, O2M, M2A)
- π Circular Dependencies: Smart handling of circular dependencies with lazy schemas
- π CRUD Schemas: Generate Create, Update, and Get schemas for each collection
- π¨ Utility Types: Use TypeScript utility types (Omit, Partial, Required) for type safety
Zodirectus automatically maps Directus field types to appropriate Zod schemas and TypeScript types:
| Directus Type | Zod Schema | TypeScript Type |
|---|---|---|
uuid |
z.string().uuid() |
string |
varchar, text |
z.string() |
string |
integer, bigint |
z.number().int() |
number |
decimal, float |
z.number() |
number |
boolean |
z.boolean() |
boolean |
date |
z.string().date() |
string |
datetime |
z.string().datetime() |
string |
json |
z.any() |
any |
Zodirectus handles the following Directus field types and interfaces:
- String Fields:
varchar,text,character varying - Numeric Fields:
integer,bigint,decimal,float,numeric,real - Boolean Fields:
boolean - Date/Time Fields:
date,datetime,timestamp,time - UUID Fields:
uuid - JSON Fields:
json,jsonb
- File Fields:
fileinterface β Single file object - Image File Fields:
file-imageinterface β Image file object with dimensions - Multiple Files:
filesinterface β Array of file objects - Repeater Fields:
repeatertype β Array of objects with sub-fields - Tag Fields:
taginterface β Array of strings or enums - Autocomplete Fields:
autocompleteinterface β String with suggestions - Checkbox Tree Fields:
select-multiple-checkbox-treeinterface β Array of enums from hierarchical structure - Dropdown Multiple Fields:
select-multiple-dropdowninterface β Array of enums - Radio Button Fields:
select-radiointerface β Single enum value - Choice Fields: Fields with
choicesoroptionsβ Enum validation
- Many-to-One (M2O): References to a single item in another collection (
post.author_idβUser) - One-to-Many (O2M): Arrays of related objects; typically exposed via the related collection (
user.postsβPost[]) - Many-to-Any (M2A): Polymorphic relations pointing to different collections (e.g.,
comment.itemcould bePostorEvent) - Many-to-Many (M2M): Arrays of related collection objects, handled via junction tables (e.g.,
student.coursesβCourse[])
- Hidden Fields:
user_created,user_updated,date_created,date_updated,status,sort - ID Fields: Automatically added if missing from collection
- Divider Fields: Automatically excluded from generation
You can provide custom field type mappings:
const zodirectus = new Zodirectus({
directusUrl: 'https://your-directus-instance.com',
token: 'your-token',
customFieldMappings: {
'custom_type': 'z.customValidator()',
'another_type': 'z.string().min(5)',
},
});- Node.js 16+
- pnpm
- Directus instance for testing
git clone https://github.com/InformationSystemsAgency/zodirectus.git
cd zodirectus
pnpm install
pnpm run buildpnpm test- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License - see LICENSE file for details.
- π Documentation
- π Issue Tracker
- π¬ Discussions
Since this package is currently hosted only on GitHub, you can install it using:
# Install as a dependency
pnpm add https://github.com/InformationSystemsAgency/zodirectus.git
# Install globally for CLI usage
pnpm add -g https://github.com/InformationSystemsAgency/zodirectus.git- Initial release
- CLI tool
- Library support
- Zod schema generation
- TypeScript type generation
- Custom field mappings