io-hipster
v0.1.11
Published
Ionic Angular standalone CRUD generator for JHipster JDL/GDL files
Maintainers
Readme
Terminal Output
___ ___ _ _ ___ ____ ____ _____ _____ ____
|_ _/ _ \ | | | |_ _| _ \/ ___|_ _| ____| _ \
| | | | |_____| |_| || || |_) \___ \ | | | _| | |_) |
| | |_| |_____| _ || || __/ ___) || | | |___| _ <
|___\___/ |_| |_|___|_| |____/ |_| |_____|_| \_\
IO-HIPSTER v0.1.8
Ionic Angular Standalone CRUD Generator
Created by Abdulla Fayyaz
Config: config/config.yml
Input: GDL/i.gdl
Preset: crud
Service: demoModule
Target: tmp/generated/demoModule
✅ Config loaded
✅ Validation passed
✅ Service folder ready: demoModule
✅ Entities generated: 2
✅ Enums generated: 2
✅ Files written: 26
⚠️ Files skipped: 0
✅ Manifest created
✅ Report created
🎉 Done successfully.What is IO-HIPSTER?
IO-HIPSTER reads JHipster JDL/GDL files and generates Ionic Angular standalone CRUD modules for any domain.
It is a reusable public npm CLI generator for inventory apps, school apps, finance apps, healthcare apps, booking apps, admin apps, and any other Ionic Angular standalone project.
Generated output includes:
- standalone Ionic Angular pages (list, detail, form)
- entity models and HttpClient services
- enums and route files
- optional typed form services (
--form-service) - service/module-based folder structure
- responsive mobile-first layouts
- Tailwind CSS utility classes by default
Install
npm install -g io-hipsterOr run directly:
npx io-hipster ./examples/demo.gdl ./tmp/generated --service demoModule --standalone --ionicUsage Modes
IO-HIPSTER supports three ways to run:
1. Config mode (recommended)
config/config.yml
GDL/i.gdlio-hipster init-config
io-hipster generate
io-hipster generate --config ./config/custom.yml2. Direct CLI mode (no config required)
io-hipster ./GDL/i.gdl ./tmp/generated \
--service demoModule \
--preset crud \
--standalone --ionic --tailwind
io-hipster ./GDL/i.gdl ./tmp/generated --service demoModule --standalone --ionic --dry-run3. Interactive mode
If you run io-hipster or io-hipster generate without a config file and without required CLI args, IO-HIPSTER prompts you to:
- Create config now
- Continue with interactive setup
- Show direct CLI usage
Interactive mode is disabled for --quiet and --ci.
Option priority
1. CLI flags
2. config/config.yml
3. interactive answers
4. safe defaultsQuick Start
Config-driven workflow
io-hipster init-config
io-hipster validate ./GDL/i.gdl
io-hipster generate --dry-run
io-hipster generate --force
io-hipster doctorDirect CLI usage
io-hipster ./GDL/i.gdl ./tmp/generated --service demoModule --standalone --ionic --dry-run
io-hipster ./GDL/i.gdl ./tmp/generated --service demoModule --standalone --ionic --forceGenerated Structure
demoModule/
entities/
customer/
model/customer.model.ts
service/customer.service.ts
pages/
customer-list/
customer-detail/
customer-form/
customer.routes.ts
order/
model/order.model.ts
service/order.service.ts
pages/
order-list/
order-detail/
order-form/
order.routes.ts
enums/
order-status.model.ts
demo-module.routes.ts
io-hipster.manifest.json
io-hipster-report.mdGenerated pages use Ionic components with Tailwind CSS utility classes by default. Use --no-tailwind for SCSS-only styling.
Commands
io-hipster init-config # create config/config.yml and GDL/i.gdl
io-hipster init # alias for init-config
io-hipster validate <file> # validate a JDL/GDL file
io-hipster generate # generate using config/config.yml
io-hipster mock # generate mock data files
io-hipster check-imports # verify generated TypeScript import paths
io-hipster doctor # check host project readiness
io-hipster <input> <output> # direct generationConfig File
io-hipster init-config creates:
config/config.ymlGDL/i.gdl
Example config/config.yml:
project:
name: Demo App
input:
file: ./GDL/i.gdl
type: gdl
output:
directory: ./tmp/generated
service: demoModule
structure: service-module
preset: crud
generate:
model: true
service: true
enums: true
routes: true
pages:
list: true
detail: true
form: true
ui:
framework: ionic
styling: tailwind
api:
baseUrl: /api
endpointStyle: kebab-plural
responseType: http-response
queryStyle: jhipster
idField: id
partialUpdate: true
delete: true
endpoints: {}
fields:
audit:
enabled: false
hideInForms: true
hideInLists: true
showInDetail: true
mock:
enabled: false
recordsPerEntity: 10
offline:
enabled: false
checks:
importPaths: false
failOnBrokenImports: false
entities:
only: []
skip: []
safety:
dryRun: true
force: false
validateBeforeGenerate: true
reports:
manifest: true
report: truePresets
| Preset | Generates |
|--------|-----------|
| model-service | models, services, enums |
| crud | models, services, enums, routes, list/detail/form pages |
| ui-only | routes and pages only |
| offline-crud | full CRUD plus SQLite tables, offline services, sync helpers |
Manual generate: settings override preset defaults:
preset: model-service
generate:
routes: trueCLI override:
io-hipster generate --preset model-service --dry-runGenerate Control
Control exactly what is generated:
generate:
model: true
service: false
enums: true
routes: false
pages:
list: true
detail: false
form: falseCLI equivalents:
io-hipster generate --skip-service
io-hipster generate --skip-pages
io-hipster generate --skip-routesEntity Filtering
entities:
only:
- Customer
- Order
skip:
- AuditLogio-hipster generate --only Customer,Order
io-hipster generate --skip-entity AuditLogLegacy flat JSON configs (io-hipster.config.json) are still supported.
CLI args override config values:
io-hipster generate --service customModule --dry-runAPI Service Customization
Control generated Angular service URLs, response types, and CRUD methods:
api:
baseUrl: /api
endpointStyle: kebab-plural # kebab-plural | kebab | camel | pascal | custom
responseType: http-response # http-response | body
queryStyle: jhipster # jhipster | simple
idField: id
partialUpdate: true
delete: true
urlMode: default # default | proxy-path | environment
modulePrefix: pmb-{service} # used by proxy-path mode
environmentKey: auto # approvalModule -> approvalModuleApiUrl
endpoints:
Customer: /api/customers
Order: /api/sales/ordersURL modes
| Mode | Generated example | Use case |
|------|-------------------|----------|
| default | `${environment.apiBaseUrl}/api/customers` | Generic apps |
| proxy-path | `/pmb-approvalModule/api/approvals` | Dev proxy (proxy.conf.json) |
| environment | `${environment.approvalModuleApiUrl}/api/approvals` | Per-module prod hosts |
Proxy-path example for approvalModule + entity Approval:
output:
service: approvalModule
api:
urlMode: proxy-path
modulePrefix: pmb-{service}
baseUrl: /api
endpointStyle: kebab-pluralGenerated service:
protected resourceUrl = `/pmb-approvalModule/api/approvals`;Pair with a proxy entry:
"/pmb-approvalModule/**": {
"target": "http://localhost:30062/",
"secure": false,
"changeOrigin": true
}Environment mode example:
api:
urlMode: environment
environmentKey: autoGenerated service:
protected resourceUrl = `${environment.approvalModuleApiUrl}/api/approvals`;Examples:
CustomerOrder+kebab-plural→/api/customer-ordersCustomerOrder+kebab→/api/customer-orderCustomerOrder+camel→/api/customerOrder- custom endpoint map →
/api/sales/orders
CLI overrides:
io-hipster generate --endpoint-style kebab-plural
io-hipster generate --response-type body
io-hipster generate --api-base-url /api/v2
io-hipster generate --url-mode proxy-path --service approvalModule
io-hipster generate --url-mode environment --service referenceModule
io-hipster generate --module-prefix pmb-{service}Audit Field Handling
Hide technical audit fields from generated UI while keeping detail visibility.
Set enabled: true to activate:
fields:
audit:
enabled: true
hideInForms: true
hideInLists: true
showInDetail: true
readonlyInForms: true
names:
- createdAt
- updatedAt
- createdBy
- updatedBy
- versionGenerated forms skip hidden audit fields. List cards show business fields first. Detail pages render an Audit Information section when enabled.
Mock Data Generation
Generate static mock files for UI development before the backend is ready:
mock:
enabled: true
recordsPerEntity: 10
mode: static
output:
directory: mock
perEntityFile: true
values:
stringPrefix: Sample
numberMin: 1
numberMax: 1000
booleanDefault: trueio-hipster mock
io-hipster mock --dry-runOutput example:
demoModule/mock/customer.mock.ts
demoModule/mock/order.mock.ts
demoModule/mock/index.tsOffline-First Preset
Optional SQLite-oriented offline generation for Ionic apps:
io-hipster generate --preset offline-crudpreset: offline-crud
offline:
enabled: true
storage: sqlite
syncQueue: true
generateMigrations: true
generateOfflineServices: true
generateSyncHelpers: true
tableNameStyle: snake_plural
moduleNameStyle: screaming_snake
databaseService:
importPath: src/app/core/database/database.service
className: DatabaseServiceGenerates per entity:
- SQLite table definitions
- offline storage services (
saveOffline,queryOffline,markAsSynced, ...) - sync payload helpers
- module-level offline migrations and sync queue models
Normal crud does not generate offline files unless offline.enabled: true.
Import Path Checker
Scan generated TypeScript files for broken relative imports:
io-hipster check-imports
io-hipster check-imports --target tmp/generated/demoModule
io-hipster check-imports --fail-on-broken-importsConfig:
checks:
importPaths: true
failOnBrokenImports: falseImport checking also runs automatically after generation when checks.importPaths is enabled.
Friendly Error Messages
IO-HIPSTER reports actionable errors by default:
❌ Unknown field type
Entity:
CustomerOrder
Field line:
bigintt totalAmount
Suggestion:
Use Long, Integer, BigDecimal, Float, Double, String, Boolean, LocalDate, Instant, UUID, or define an enum named Bigintt.Output modes:
- default: friendly message with suggestions
--verbose: extra context--debug: full stack trace--quiet: short error only--ci: non-zero exit codes for automation
Starter GDL
Default GDL/i.gdl:
enum TaskStatus { TODO, IN_PROGRESS, DONE, CANCELLED }
enum Priority { LOW, MEDIUM, HIGH }
entity Project {
string name required
string description
instant startDate
boolean active
}
entity Task {
string title required
string description
TaskStatus status
Priority priority
instant dueDate
boolean completed
}
relationship ManyToOne {
Task{project} to Project
}Options
--force overwrite existing files
--dry-run print files that would be generated without writing
--standalone generate standalone Angular components
--ionic generate Ionic UI
--tailwind generate Tailwind utility classes in Ionic templates (default)
--no-tailwind generate without Tailwind utility classes
--service service/module folder name, e.g. demoModule
--module alias for --service
--api-base-url API base segment, default /api
--module-routes generate service/module-level route file
--form-service generate a typed Angular form service per entity (JHipster style)
--shared-enums generate enums into src/app/shared/enums
--skip-validation skip validation before generation
--strict fail on validation warnings
--ci CI mode: no prompts, no banner, validation required
--dry-run-report create manifest/report even during a dry run
--update-report update manifest/report even if all files are skipped
--skip-pages skip page generation
--skip-service skip service generation
--skip-model skip model generation
--skip-enums skip enum generation
--no-banner suppress startup banner
--quiet suppress banner and non-essential progress logs
--verbose print every generated, skipped, or dry-run file
--debug print full error stack on failureTailwind CSS
Tailwind utility classes are enabled by default in generated Ionic templates.
io-hipster ./GDL/i.gdl ./tmp/generated --service demoModule --no-tailwindRun io-hipster doctor to verify Tailwind is configured in your host project.
Form Service
By default, form pages build reactive forms inline with FormBuilder.group(...).
Pass --form-service to generate a JHipster-style typed form service per entity:
io-hipster ./GDL/i.gdl ./tmp/generated --service demoModule --form-serviceThis produces <entity>-form.service.ts with:
- typed
XxxFormGroup createXxxFormGroup(entity?)getXxx(form)resetForm(form, entity)
Validation
io-hipster validate
io-hipster validate ./GDL/i.gdl
io-hipster validate ./examples/demo.gdl --strictWhen no file is passed, validate reads input.file from config/config.yml.
Validation checks entities, fields, primitive types, enum references, relationship targets, duplicate names, and TypeScript reserved words.
Doctor
io-hipster doctorGeneric checks only:
- Angular detected
- Ionic Angular detected
- standalone support
- Tailwind detected (if used)
app.routes.tsfound- environment file found
apiBaseUrlfound if configured- HttpClient provider found or warning shown
Manifest and Report
Each successful generation can write:
io-hipster.manifest.jsonio-hipster-report.md
Example manifest:
{
"generator": "io-hipster",
"version": "0.1.8",
"configFile": "config/config.yml",
"input": "./GDL/i.gdl",
"service": "demoModule",
"entities": ["customer", "order"],
"enums": ["order-status"],
"filesWritten": 26,
"filesSkipped": 0
}Generated Code
Generated Angular code:
- uses standalone components
- uses Ionic standalone imports
- uses responsive mobile-first SCSS
- uses Tailwind utility classes by default (unless
--no-tailwind) - uses
HttpClientand reactive forms - avoids Angular NgModules
- includes generic generated headers only
Example generated header:
// Generated by IO-HIPSTER.
// Generator: io-hipster
// Safe to edit. Use --force carefully because it can overwrite changes.Route Integration
Mount generated entity routes in app.routes.ts:
{
path: 'orders',
loadChildren: () =>
import('./domains/demoModule/entities/order/order.routes').then(
(m) => m.ORDER_ROUTES,
),
}If --module-routes is used, mount the module route file instead:
{
path: 'demo',
loadChildren: () =>
import('./domains/demoModule/demo-module.routes').then(
(m) => m.DEMO_MODULE_ROUTES,
),
}Domain Example
Optional domain-specific samples are kept under examples/domains/ for reference only. They are not used by default config, tests, or CLI output.
examples/
demo.gdl
domains/
approval/sample-approval.gdl
pmb/sample-pmb.jdl
pmb/sample-pmb.gdlDevelopment
npm install
npm run build
npm test
node bin/io-hipster.js init-config --force
node bin/io-hipster.js validate ./GDL/i.gdl
node bin/io-hipster.js generate --dry-run
node bin/io-hipster.js generate --force
node bin/io-hipster.js doctor
node bin/io-hipster.js ./GDL/i.gdl ./tmp/generated --service demoModule --standalone --ionic --dry-runCI Mode
io-hipster generate --ci- No prompts or banner
- Validation required unless
--skip-validation - Non-zero exit on errors (and warnings when
--strict) - Short output for pipelines
Changelog
Config-first flexible generation
- YAML config at
config/config.ymlwith presets (model-service,crud,ui-only) - Granular
generate:controls for models, services, enums, routes, and individual pages - Three usage modes: config, direct CLI, interactive
- Option priority: CLI → config → interactive → defaults
io-hipster validatewithout args reads config input--preset,--only,--skip-entity,--config,--skip-routesCLI flags- Entity filtering with required enum generation for selected entities
- Enhanced manifest/report with preset and generated-parts summary
Generic public CLI refactor
- Default config is now
config/config.ymlwith genericdemoModuleservice name. init-configcreatesconfig/config.ymland starterGDL/i.gdl(Project/Task sample).- README, tests, manifest/report examples, and CLI output are domain-neutral.
- Optional domain-specific samples moved to
examples/domains/. - Legacy
io-hipster.config.jsonremains supported.
Optional typed form service
- Added
--form-servicefor JHipster-style typed form services (off by default).
Tailwind UI, validation, config, doctor, and manifest/report
- Tailwind + Ionic page output,
validate,init/generate,doctor, manifest/report,--strict,--ci, and related CLI options.
Limitations
- Frontend generator only (no backend generation).
- Relationship option loading is intentionally simple.
- Generated code may need small host-project route/icon registration adjustments.
Author
Abdulla Fayyaz
License
MIT
