@validkeys/ollypop-ts
v1.1.2
Published
Automatic TypeScript barrel file generator CLI.
Maintainers
Readme
Ollypop
Automatic TypeScript Barrel File Generation
Overview
Ollypop is a CLI tool for generating TypeScript barrel files (index.ts) automatically. It uses a powerful variable-based template system to scan directories and files, creating export statements based on your configuration. The system supports both directory-based and file-based patterns, with intelligent file existence filtering and path resolution relative to the output file location.
Features
- Variable-based export templates: Use
{dir}or{file}placeholders in your export statements - Chained transformations: Apply casing, singular/plural, prefix/suffix, and more
- Automatic pattern detection: Scans for files or directories based on your template
- File existence filtering: Only exports items that actually exist
- Partial replace mode: Update only the auto-generated section of a file
- No
cwdrequired: All paths are resolved relative to the output file - Dry run mode: Preview changes before writing
Quick Start
- Install dependencies
pnpm install - Create a configuration file
pnpm exec ollypop init # Or copy and edit barrel.config.json - Generate barrels
pnpm exec ollypop generate - Run examples
# Run all examples to see different patterns pnpm run examples # Or run individual examples pnpm run example:basic # File-based without extensions pnpm run example:directory # Directory-based without extensions pnpm run example:with-extensions # File-based with .js extensions pnpm run example:directory-extensions # Directory-based with .js extensions
Configuration
Configuration is defined in barrel.config.json:
{
"version": "1.0",
"barrels": [
{
"name": "handlers",
"output": "./src/handlers/index.ts",
"template": {
"name": "variable-template",
"export": "export * from './{dir:raw}/index.js'"
},
"options": {
"preserveExtensions": true,
"extensions": [".ts"],
"validateExports": false,
"dryRun": false
}
},
{
"name": "interfaces",
"output": "./src/index.browser.ts",
"template": {
"name": "variable-template",
"export": "export * from './handlers/{dir:raw}/interface.js'",
"mode": "partial-replace"
},
"options": {
"preserveExtensions": true,
"extensions": [".ts"],
"validateExports": false,
"dryRun": false
}
}
]
}Template System
- Variables:
{dir}for directory names,{file}for file names - Transforms:
{dir:raw},{dir:camel},{dir:pascal},{dir:kebab},{dir:singular},{dir:plural},{dir:trimPrefix:foo-},{dir:addSuffix:Bar} - Chaining:
{dir:trimPrefix:foo-|pascal|plural} - Partial Replace: Use
mode: "partial-replace"to update only the marked section of a file
Transformations Reference
The variable template system supports a wide range of transformations for directory and file names. You can chain multiple transformations using the pipe (|) operator.
| Syntax | Description | Example Input | Example Output |
| ------------------------------------ | ---------------------------------------- | -------------------- | ------------------ |
| {dir} | PascalCase (default) | user-profile | UserProfile |
| {dir:raw} | Preserve original | user-profile | user-profile |
| {dir:camel} | camelCase | user-profile | userProfile |
| {dir:kebab} | kebab-case | UserProfile | user-profile |
| {dir:pascal} | PascalCase | user-profile | UserProfile |
| {dir:singular} | Singularize (inflection) | account-balances | account-balance |
| {dir:plural} | Pluralize (inflection) | account-balance | account-balances |
| {dir:trimPrefix:warehouse-,ops-} | Remove specified prefixes | warehouse-accounts | accounts |
| {dir:trimSuffix:Service,Manager} | Remove specified suffixes | AccountService | Account |
| {dir:addPrefix:I,Base} | Add specified prefix | Account | IAccount |
| {dir:addSuffix:Factory,Service} | Add specified suffix | Account | AccountFactory |
| {dir:replace:old,new;acct,account} | Replace text (semicolon-separated pairs) | old-acct-data | new-account-data |
| {dir:uppercase} | Convert to uppercase | account | ACCOUNT |
| {dir:lowercase} | Convert to lowercase | ACCOUNT | account |
| {dir:capitalize} | Capitalize first letter | account | Account |
| {dir:uncapitalize} | Lowercase first letter | Account | account |
Chained Transformations
You can chain multiple transformations using the pipe operator:
{
"template": {
"name": "variable-template",
"export": "export * as {dir:trimPrefix:warehouse-,ops-|singular|pascal}Factory from './{dir:raw}/factory.js'"
}
}Transformation Flow:
warehouse-account-balances→ trimPrefix →account-balancesaccount-balances→ singular →account-balanceaccount-balance→ pascal →AccountBalance- Final result:
AccountBalanceFactory
Configuration Examples & Resulting Barrel Output
1. Directory-Based Barrel
Config:
{
"template": {
"name": "variable-template",
"export": "export * from './{dir:raw}/index.js'"
}
}Directory Structure:
src/handlers/
├── createUser/
│ └── index.ts
├── updateProfile/
│ └── index.ts
└── deleteAccount/
└── interface.tsResulting Barrel:
export * from './createUser/index.js';
export * from './updateProfile/index.js';
// deleteAccount excluded (no index.ts)2. File-Based Barrel
Config:
{
"template": {
"name": "variable-template",
"export": "export * from './{file:raw}.ts'"
}
}Directory Structure:
src/primitives/
├── accountType.ts
├── assetType.ts
├── currency.ts
├── index.ts (barrel file, auto-excluded)
└── logging.tsResulting Barrel:
export * from './accountType.ts';
export * from './assetType.ts';
export * from './currency.ts';
export * from './logging.ts';
// index.ts excluded automatically3. Interface Barrel (Partial Replace)
Config:
{
"template": {
"name": "variable-template",
"export": "export * from './handlers/{dir:raw}/interface.js'",
"mode": "partial-replace"
}
}Directory Structure:
src/handlers/
├── createUser/
│ ├── index.ts
│ └── interface.ts
├── updateProfile/
│ └── index.ts (no interface.ts)
└── deleteAccount/
└── interface.tsResulting Barrel Section:
// AUTO-GENERATED EXPORTS - START
export * from './handlers/createUser/interface.js';
export * from './handlers/deleteAccount/interface.js';
// AUTO-GENERATED EXPORTS - END4. Advanced Naming with Chained Transforms
Config:
{
"template": {
"name": "variable-template",
"export": "export * as {dir:singular|pascal}Service from './{dir:raw}/service.js'"
}
}Directory Structure:
src/services/
├── accounts/
│ └── service.ts
├── payments/
│ └── service.tsResulting Barrel:
export * as AccountService from './accounts/service.js';
export * as PaymentService from './payments/service.js';5. Multi-Level Variables (Future/Advanced)
Config:
{
"template": {
"name": "variable-template",
"export": "export * as {namespace:raw}{Entity:pascal}Factory from './{namespace:raw}/{Entity:raw}/factory.js'"
}
}Directory Structure:
src/domains/
├── warehouse/
│ └── product/
│ └── factory.ts
├── retail/
│ └── customer/
│ └── factory.tsResulting Barrel:
export * as warehouseProductFactory from './warehouse/product/factory.js';
export * as retailCustomerFactory from './retail/customer/factory.js';CLI Commands
Ollypop provides several commands for managing barrel file generation:
Generate
Generate barrel files based on your configuration:
ollypop generate [options]Options:
--config <path>- Path to configuration file (default: "barrel.config.json")--dry-run- Preview changes without writing files--verbose- Show detailed generation information
Example:
ollypop generate --config my-config.json --verboseValidate
Validate your configuration file for syntax errors:
ollypop validate [options] Options:
--config <path>- Path to configuration file (default: "barrel.config.json")
Example:
ollypop validate --config my-config.jsonThis command validates:
- Export template syntax (proper quoting, variables)
- Configuration file structure
- Path resolution logic
Initialize
Create a sample configuration file:
ollypop init [options]Options:
--config <path>- Path for new configuration file (default: "barrel.config.json")
Common Template Errors
If you encounter template syntax errors, see Export Template Validation for detailed troubleshooting guide.
Quick fixes for common issues:
- Ensure paths are quoted:
"./handlers/{handler}"not./handlers/{handler} - Use matching quotes:
"..."or'...'but not mixed - Include variables:
{variable}in curly braces
