Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ directus-typeforge [options]
## Available Options

| Option | Alias | Description | Default |
| --------------------------- | ----- | -------------------------------------------------------------------------- | ---------------- |
| --------------------------- | ----- |----------------------------------------------------------------------------| ---------------- |
| `--snapshotFile` | `-i` | Path to schema snapshot file | - |
| `--host` | `-h` | Directus host URL | - |
| `--email` | `-e` | Email for authentication | - |
Expand All @@ -74,6 +74,8 @@ directus-typeforge [options]
| `--exportSystemCollections` | `-x` | Export system collections in root schema | `true` |
| `--resolveSystemRelations` | `-y` | Resolve system collection relationships (e.g. directus_files.folder) | `true` |
| `--addTypedocNotes` | `-d` | Add JSDoc comments from field notes | `true` |
| `--typeMappings` | | Custom collection-to-type mappings (e.g. `kurs:Kurs,ausweis:Ausweis`) | - |
| `--noSingularize` | | Disable automatic singularization of collection names | `false` |
| `--timestamp` | | Include generation timestamp in output header | `false` |
| `--debug` | | Enable debug logging | `false` |
| `--logLevel` | | Set log level (error, warn, info, debug, trace) | `info` |
Expand Down Expand Up @@ -128,6 +130,12 @@ npx directus-typeforge -i schema-snapshot.json -u -o ./types/schema.ts
# Include generation timestamp in output header
npx directus-typeforge -i schema-snapshot.json --timestamp -o ./types/schema.ts

# Custom type mappings (useful for non-English collection names)
npx directus-typeforge -i schema-snapshot.json --typeMappings "kurs:Kurs,ausweis:Ausweis" -o ./types/schema.ts

# Disable singularization entirely (useful for non-English projects)
npx directus-typeforge -i schema-snapshot.json --noSingularize -o ./types/schema.ts

# Enable debug logging to troubleshoot issues
npx directus-typeforge -i schema-snapshot.json --debug --logLevel debug --logFile ./typeforge-debug.log -o ./types/schema.ts
```
Expand Down
22 changes: 22 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ const main = async (): Promise<void> => {
description: "Include generation timestamp in output header",
default: false,
})
.option("typeMappings", {
type: "string",
description: "Custom collection-to-type mappings (e.g. kurs:Kurs,ausweis:Ausweis)",
})
.option("noSingularize", {
type: "boolean",
description: "Disable automatic singularization of collection names",
default: false,
})
.option("debug", {
type: "boolean",
description: "Enable debug logging",
Expand Down Expand Up @@ -215,6 +224,17 @@ const main = async (): Promise<void> => {
token: argv.token,
};

// Parse type mappings from CLI string format (e.g. "kurs:Kurs,kurse:Kurse")
const typeMappings: Record<string, string> = {};
if (argv.typeMappings) {
for (const pair of argv.typeMappings.split(",")) {
const [collection, typeName] = pair.split(":");
if (collection && typeName) {
typeMappings[collection.trim()] = typeName.trim();
}
}
}

// Generate TypeScript types with dynamic system field detection
spinner.text = "Generating TypeScript types...";
const ts = await generateTypeScript(
Expand All @@ -230,6 +250,8 @@ const main = async (): Promise<void> => {
resolveSystemRelations: argv.resolveSystemRelations,
addTypedocNotes: argv.addTypedocNotes,
includeTimestamp: argv.timestamp,
typeMappings: Object.keys(typeMappings).length > 0 ? typeMappings : undefined,
noSingularize: argv.noSingularize,
},
schemaOptions
);
Expand Down
10 changes: 10 additions & 0 deletions src/services/CoreSchemaProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ export class CoreSchemaProcessor {
resolveSystemRelations: options.resolveSystemRelations ?? true,
addTypedocNotes: options.addTypedocNotes ?? true,
includeTimestamp: options.includeTimestamp ?? false,
typeMappings: options.typeMappings ?? {},
noSingularize: options.noSingularize ?? false,
};

// Initialize component managers
Expand Down Expand Up @@ -1013,6 +1015,13 @@ export class CoreSchemaProcessor {
return typeName;
}

// Check custom type mappings first
if (this.options.typeMappings && collectionName in this.options.typeMappings) {
const typeName = this.options.typeMappings[collectionName];
this.collectionTypes.set(collectionName, typeName);
return typeName;
}

// For regular collections, convert to PascalCase singular (unless it's a singleton)
const isSingletonCollection = this.isSingleton(collectionName);
const pascalName = toPascalCase(collectionName);
Expand All @@ -1038,6 +1047,7 @@ export class CoreSchemaProcessor {
* Convert plural to singular using pluralize library
*/
private makeSingular(name: string): string {
if (this.options.noSingularize) return name;
return pluralize.singular(name);
}

Expand Down
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export type GenerateTypeScriptOptions = {
resolveSystemRelations?: boolean; // Resolve system collection internal relationships (e.g. directus_files.folder -> DirectusFolder)
addTypedocNotes?: boolean; // Add JSDoc comments from field notes
includeTimestamp?: boolean; // Include generation timestamp in output header (default: false)
typeMappings?: Record<string, string>; // Custom collection name to type name mappings (e.g. { "kurs": "Kurs" })
noSingularize?: boolean; // Disable automatic singularization of collection names
};

/**
Expand Down