create-odoo-module 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/LICENSE +21 -0
- package/README.md +309 -0
- package/bin/create-odoo-module.js +147 -0
- package/package.json +84 -0
- package/src/cli/args-parser.js +36 -0
- package/src/cli/index.js +272 -0
- package/src/cli/prompts.js +151 -0
- package/src/cli/validator.js +72 -0
- package/src/config/defaults.js +41 -0
- package/src/config/pro-config.js +55 -0
- package/src/generators/api-generator.js +340 -0
- package/src/generators/deploy-generator.js +390 -0
- package/src/generators/flutter-generator.js +1695 -0
- package/src/generators/odoo-generator.js +794 -0
- package/src/generators/ui-generator.js +329 -0
- package/src/utils/file-system.js +67 -0
- package/src/utils/license-check.js +57 -0
- package/src/utils/logger.js +32 -0
- package/src/utils/spinner.js +32 -0
- package/src/utils/string-utils.js +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `create-odoo-module` are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
|
+
Versioning follows [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## [1.0.0] — 2026-06-20
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Core CLI** with `commander.js` — argument parsing, subcommands (`list`, `upgrade`)
|
|
13
|
+
- **Interactive mode** via `inquirer.js` — guided setup when no flags given
|
|
14
|
+
- **Odoo module generator** — produces complete Python module:
|
|
15
|
+
- `__manifest__.py` with correct version format (`17.0.1.0.0`)
|
|
16
|
+
- `models/` — full model with state machine, constraints, computed fields, sequence
|
|
17
|
+
- `security/` — CSV access rules + XML security groups
|
|
18
|
+
- `data/` — auto-sequence record
|
|
19
|
+
- `static/` — JS + SCSS placeholders
|
|
20
|
+
- `i18n/` — `.pot` translation template
|
|
21
|
+
- `tests/` — 10 pytest tests covering full lifecycle (with `--with-tests`)
|
|
22
|
+
- `wizard/` — transient model bulk-action dialog (with `--with-wizard`)
|
|
23
|
+
- `report/` — QWeb PDF report + template (with `--with-reports`)
|
|
24
|
+
- OWL component with `@odoo/owl` (with `--with-owl`)
|
|
25
|
+
- **REST API generator** — full CRUD controller:
|
|
26
|
+
- `GET /api/{module}` with pagination, search, filter
|
|
27
|
+
- `GET /api/{module}/:id`
|
|
28
|
+
- `POST /api/{module}` (create)
|
|
29
|
+
- `PUT /api/{module}/:id` (update)
|
|
30
|
+
- `DELETE /api/{module}/:id` (delete, state-guarded)
|
|
31
|
+
- `POST /api/{module}/:id/action` (business methods)
|
|
32
|
+
- `GET /api/{module}/stats` (aggregate by state)
|
|
33
|
+
- Standardised `{status, data, meta}` JSON responses
|
|
34
|
+
- **UI/Views generator** — full XML views suite:
|
|
35
|
+
- Search view with filters, separators, Group By options
|
|
36
|
+
- Form view with statusbar, ribbon, chatter, priority stars
|
|
37
|
+
- List view with decoration rules, inline action buttons
|
|
38
|
+
- Kanban view with `many2one_avatar_user`
|
|
39
|
+
- Activity view
|
|
40
|
+
- `ir.actions.act_window` wiring all views
|
|
41
|
+
- Top-level + sub-menus with icon
|
|
42
|
+
- **Flutter app generator** — production-ready Dart app:
|
|
43
|
+
- `pubspec.yaml` — `odoo_rpc`, `flutter_riverpod`, `go_router`, `flutter_secure_storage`
|
|
44
|
+
- `OdooConfig` — server URL + DB constants
|
|
45
|
+
- `OdooJsonRpcClient` — typed `callKw` wrapper with typed exceptions
|
|
46
|
+
- `AuthService` — login / logout with `SharedPreferences`
|
|
47
|
+
- Typed `{Module}Record` — `fromMap`, `toMap`, `copyWith`, computed getters
|
|
48
|
+
- `{Module}Repository` — full CRUD + business action calls
|
|
49
|
+
- Riverpod `AsyncNotifier` with pagination, refresh, loadMore
|
|
50
|
+
- 4 screens: Login, List (search + pull-to-refresh), Detail (actions), Create
|
|
51
|
+
- `StateBadge`, `LoadingOverlay`, `{Module}Card` widgets
|
|
52
|
+
- Unit tests for Dart model
|
|
53
|
+
- Integration test scaffold
|
|
54
|
+
- **Deploy generator**:
|
|
55
|
+
- `deploy.sh` (Linux/macOS) — file copy + XML-RPC install/upgrade
|
|
56
|
+
- `deploy.ps1` (Windows PowerShell) — equivalent
|
|
57
|
+
- `docker-compose.yml` — Odoo + PostgreSQL local dev stack
|
|
58
|
+
- `odoo.conf` — Odoo config for Docker
|
|
59
|
+
- GitHub Actions CI pipeline (with `--with-ci`)
|
|
60
|
+
- **Module name validator** — reserved names, length, pattern
|
|
61
|
+
- **String utilities** — `toSnakeCase`, `toPascalCase`, `toKebabCase`, `toOdooModel`
|
|
62
|
+
- **Pro license verification** — API-based, cached 24h, fail-open
|
|
63
|
+
- **Update notifier** — alerts when a newer version is available
|
|
64
|
+
- **Coloured banner** — gradient ASCII art via `gradient-string` + `boxen`
|
|
65
|
+
- **Jest test suite** — 40+ tests across CLI, generators, string utils
|
|
66
|
+
- **ESLint** config
|
|
67
|
+
- Supports **Odoo 16, 17, 18**
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## [Unreleased]
|
|
72
|
+
|
|
73
|
+
### Planned for v1.1.0
|
|
74
|
+
- `upgrade` command — update existing generated projects to newer templates
|
|
75
|
+
- Pro template: `fleet` — Fleet Management
|
|
76
|
+
- Pro template: `hr` — Human Resources
|
|
77
|
+
- Pro template: `inventory` — Inventory + barcode
|
|
78
|
+
- Pro template: `pos` — Point of Sale
|
|
79
|
+
- Pro template: `crm` — CRM Pipeline with OWL dashboard
|
|
80
|
+
- `--with-graphql` flag — GraphQL endpoint via Strawberry
|
|
81
|
+
- Supabase / PostgreSQL direct integration option
|
|
82
|
+
- Windows CI runner in GitHub Actions
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 create-odoo-module contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# create-odoo-module
|
|
2
|
+
|
|
3
|
+
> **Next.js for Odoo. One command. Full-stack ERP + Flutter app in seconds.**
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/create-odoo-module)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx create-odoo-module my-module --with-api --with-ui
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
One command generates a **full Odoo Python module** + **REST API** + **Flutter mobile app**, wired together and ready to deploy — in under 30 seconds.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
- [Why?](#why)
|
|
20
|
+
- [Quick Start](#quick-start)
|
|
21
|
+
- [Options & Flags](#options--flags)
|
|
22
|
+
- [What Gets Generated?](#what-gets-generated)
|
|
23
|
+
- [Examples](#examples)
|
|
24
|
+
- [Pro Templates](#pro-templates)
|
|
25
|
+
- [Requirements](#requirements)
|
|
26
|
+
- [Publish to npm](#publish-to-npm)
|
|
27
|
+
- [Contributing](#contributing)
|
|
28
|
+
- [License](#license)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Why?
|
|
33
|
+
|
|
34
|
+
Setting up an Odoo module from scratch takes:
|
|
35
|
+
|
|
36
|
+
| Task | Without tool | With create-odoo-module |
|
|
37
|
+
|------------------------------|:------------:|:-----------------------:|
|
|
38
|
+
| Python venv + dependencies | ~30 min | **0 min** |
|
|
39
|
+
| `__manifest__.py` setup | ~20 min | **instant** |
|
|
40
|
+
| Model + Views + Menus | ~90 min | **instant** |
|
|
41
|
+
| REST API controller | ~120 min | **instant** |
|
|
42
|
+
| Flutter app wired to Odoo | ~480 min | **instant** |
|
|
43
|
+
| Deploy scripts | ~60 min | **instant** |
|
|
44
|
+
| **Total** | **~8 hours** | **< 30 seconds** |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
### Interactive mode (recommended for new users)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx create-odoo-module
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Answers a few questions, generates everything.
|
|
57
|
+
|
|
58
|
+
### Fully non-interactive
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx create-odoo-module fleet-manager \
|
|
62
|
+
--with-api \
|
|
63
|
+
--with-ui \
|
|
64
|
+
--with-tests \
|
|
65
|
+
--with-reports \
|
|
66
|
+
--odoo-version 17 \
|
|
67
|
+
--author "Acme Corp" \
|
|
68
|
+
--no-interactive
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### After generation
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
cd fleet-manager
|
|
75
|
+
cp .env.example .env # Fill in Odoo URL, DB, credentials
|
|
76
|
+
npm run dev # Start local Odoo via Docker Compose
|
|
77
|
+
npm run deploy # Upload & install module in Odoo
|
|
78
|
+
npm run flutter:run # Launch Flutter app
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Options & Flags
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Arguments:
|
|
87
|
+
[module-name] Name of your Odoo module (e.g. fleet-manager)
|
|
88
|
+
|
|
89
|
+
Options:
|
|
90
|
+
--with-api Include REST API controllers (GET/POST/PUT/DELETE)
|
|
91
|
+
--with-ui Include Flutter mobile app (login + CRUD screens)
|
|
92
|
+
--with-tests Include Python pytest + Dart flutter_test files
|
|
93
|
+
--with-reports Include QWeb PDF report template
|
|
94
|
+
--with-owl Include OWL JavaScript components
|
|
95
|
+
--with-wizard Include wizard (transient model dialog)
|
|
96
|
+
--with-docker Include Docker Compose dev environment (default: true)
|
|
97
|
+
--with-ci Include GitHub Actions CI/CD pipeline
|
|
98
|
+
--odoo-version <ver> Target Odoo version: 16 | 17 | 18 (default: 17)
|
|
99
|
+
--template <name> Use a Pro template: fleet | hr | inventory | pos | crm
|
|
100
|
+
--pro-key <key> Pro license key for premium templates
|
|
101
|
+
--author <name> Module author / company name (default: "Your Company")
|
|
102
|
+
--website <url> Author website
|
|
103
|
+
--category <cat> Odoo app category (default: "Custom")
|
|
104
|
+
--depends <modules> Extra Odoo depends, comma-separated (e.g. "sale,account")
|
|
105
|
+
--no-interactive Skip all interactive prompts (use flags only)
|
|
106
|
+
--no-git Skip git init in generated project
|
|
107
|
+
--verbose Show verbose output
|
|
108
|
+
-v, --version Output current version
|
|
109
|
+
-h, --help Display help
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Subcommands
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npx create-odoo-module list # List all Pro templates
|
|
116
|
+
npx create-odoo-module upgrade <path> # Upgrade existing project (v1.1.0+)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## What Gets Generated?
|
|
122
|
+
|
|
123
|
+
Running:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx create-odoo-module fleet-manager --with-api --with-ui --with-tests
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Produces:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
fleet-manager/
|
|
133
|
+
│
|
|
134
|
+
├── 📁 odoo_module/ ← Full Odoo Python module
|
|
135
|
+
│ ├── __init__.py
|
|
136
|
+
│ ├── __manifest__.py ← Auto-configured manifest
|
|
137
|
+
│ ├── models/
|
|
138
|
+
│ │ └── fleet_manager.py ← Full model: fields, states, CRUD, constraints
|
|
139
|
+
│ ├── views/
|
|
140
|
+
│ │ ├── fleet_manager_views.xml ← Form + List + Kanban + Activity + Search
|
|
141
|
+
│ │ └── fleet_manager_menus.xml ← Top-level + sub-menus
|
|
142
|
+
│ ├── controllers/
|
|
143
|
+
│ │ └── fleet_manager_controller.py ← REST API: GET/POST/PUT/DELETE + stats
|
|
144
|
+
│ ├── security/
|
|
145
|
+
│ │ ├── ir.model.access.csv ← ACL rules
|
|
146
|
+
│ │ └── fleet_manager_security.xml ← Groups
|
|
147
|
+
│ ├── data/
|
|
148
|
+
│ │ └── fleet_manager_data.xml ← Sequence
|
|
149
|
+
│ ├── report/ ← QWeb PDF (with --with-reports)
|
|
150
|
+
│ ├── wizard/ ← Bulk action wizard (with --with-wizard)
|
|
151
|
+
│ ├── tests/ ← pytest suite (with --with-tests)
|
|
152
|
+
│ ├── static/src/
|
|
153
|
+
│ │ ├── js/fleet_manager.js ← OWL component (with --with-owl)
|
|
154
|
+
│ │ └── scss/fleet_manager.scss
|
|
155
|
+
│ └── i18n/fleet_manager.pot
|
|
156
|
+
│
|
|
157
|
+
├── 📁 flutter_app/ ← Flutter app (with --with-ui)
|
|
158
|
+
│ ├── lib/
|
|
159
|
+
│ │ ├── main.dart ← Entry point + Material 3 theme
|
|
160
|
+
│ │ └── src/
|
|
161
|
+
│ │ ├── config/odoo_config.dart
|
|
162
|
+
│ │ ├── core/ ← JSON-RPC client + auth service + exceptions
|
|
163
|
+
│ │ ├── models/ ← Typed Dart model with fromMap / toMap
|
|
164
|
+
│ │ ├── repositories/ ← CRUD data layer + Riverpod providers
|
|
165
|
+
│ │ ├── screens/ ← Login + List + Detail + Create screens
|
|
166
|
+
│ │ └── widgets/ ← Card + StateBadge + LoadingOverlay
|
|
167
|
+
│ └── test/ ← Flutter unit tests
|
|
168
|
+
│
|
|
169
|
+
├── 📁 scripts/
|
|
170
|
+
│ ├── deploy.sh ← Linux/macOS deploy via xmlrpc
|
|
171
|
+
│ ├── deploy.ps1 ← Windows PowerShell deploy
|
|
172
|
+
│ ├── docker-compose.yml ← Odoo + PostgreSQL dev stack
|
|
173
|
+
│ └── odoo.conf ← Odoo config for Docker
|
|
174
|
+
│
|
|
175
|
+
├── .env.example ← Environment variable template
|
|
176
|
+
├── .gitignore
|
|
177
|
+
├── package.json ← npm scripts: deploy, dev, flutter:*
|
|
178
|
+
└── README.md
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Generated Model features
|
|
182
|
+
|
|
183
|
+
- `name`, `reference` (auto-sequence), `description`, `active`, `color`
|
|
184
|
+
- `state` with full state machine: draft → confirmed → in_progress → done | cancelled
|
|
185
|
+
- `user_id`, `company_id`, `tag_ids` relational fields
|
|
186
|
+
- `date_start`, `date_end`, `duration_days` (computed)
|
|
187
|
+
- `priority` (stars widget)
|
|
188
|
+
- `@api.constrains` date validation
|
|
189
|
+
- `_sql_constraints` unique reference
|
|
190
|
+
- `mail.thread` + `mail.activity.mixin` (chatter)
|
|
191
|
+
- Business methods: `action_confirm`, `action_start`, `action_done`, `action_cancel`, `action_reset_draft`
|
|
192
|
+
|
|
193
|
+
### Generated REST API endpoints
|
|
194
|
+
|
|
195
|
+
| Method | Endpoint | Description |
|
|
196
|
+
|--------|----------|-------------|
|
|
197
|
+
| `GET` | `/api/{module}` | List records (pagination, search, filter) |
|
|
198
|
+
| `GET` | `/api/{module}/:id` | Get single record |
|
|
199
|
+
| `POST` | `/api/{module}` | Create record |
|
|
200
|
+
| `PUT` | `/api/{module}/:id` | Update record |
|
|
201
|
+
| `DELETE` | `/api/{module}/:id` | Delete record |
|
|
202
|
+
| `POST` | `/api/{module}/:id/action` | Call business action |
|
|
203
|
+
| `GET` | `/api/{module}/stats` | Aggregate stats by state |
|
|
204
|
+
|
|
205
|
+
All endpoints return standardised JSON: `{ status: "success"|"error", data: ..., meta: ... }`.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Examples
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Basic module (no API, no Flutter)
|
|
213
|
+
npx create-odoo-module hospital-records
|
|
214
|
+
|
|
215
|
+
# Full stack: Odoo 18 + REST API + Flutter
|
|
216
|
+
npx create-odoo-module patient-manager --with-api --with-ui --odoo-version 18
|
|
217
|
+
|
|
218
|
+
# With tests + reports + OWL components
|
|
219
|
+
npx create-odoo-module maintenance-tracker \
|
|
220
|
+
--with-api --with-tests --with-reports --with-owl
|
|
221
|
+
|
|
222
|
+
# Extra Odoo dependencies
|
|
223
|
+
npx create-odoo-module pos-extension \
|
|
224
|
+
--depends "point_of_sale,account" \
|
|
225
|
+
--odoo-version 17
|
|
226
|
+
|
|
227
|
+
# CI/CD pipeline included
|
|
228
|
+
npx create-odoo-module my-module --with-ci --with-tests
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Pro Templates
|
|
234
|
+
|
|
235
|
+
Premium pre-built templates for common industry scenarios:
|
|
236
|
+
|
|
237
|
+
| Template | Description | Includes |
|
|
238
|
+
|----------|-------------|----------|
|
|
239
|
+
| `fleet` | Fleet Management | Vehicle tracking, maintenance, fuel logs |
|
|
240
|
+
| `hr` | Human Resources | Employees, contracts, payroll |
|
|
241
|
+
| `inventory` | Inventory | Products, lots, barcode scanner |
|
|
242
|
+
| `pos` | Point of Sale | POS extension, custom payments |
|
|
243
|
+
| `crm` | CRM Pipeline | Leads, pipeline, OWL dashboard |
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# List templates
|
|
247
|
+
npx create-odoo-module list
|
|
248
|
+
|
|
249
|
+
# Use a Pro template
|
|
250
|
+
npx create-odoo-module my-fleet --template fleet --pro-key YOUR_KEY
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Get Pro access:** https://create-odoo-module.dev/pro ($19/month)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Requirements
|
|
258
|
+
|
|
259
|
+
| Requirement | Version | Notes |
|
|
260
|
+
|-------------|---------|-------|
|
|
261
|
+
| **Node.js** | ≥ 18 | Required to run the CLI |
|
|
262
|
+
| **Docker** | Any | Optional — for local Odoo via Docker Compose |
|
|
263
|
+
| **Flutter SDK** | ≥ 3.19 | Required only with `--with-ui` |
|
|
264
|
+
| **Git** | Any | Optional — for git init in generated project |
|
|
265
|
+
|
|
266
|
+
No Python required on your machine — Python code is deployed to Odoo server.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Publish to npm
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# 1. Login to npm
|
|
274
|
+
npm login
|
|
275
|
+
|
|
276
|
+
# 2. Dry run to verify what will be published
|
|
277
|
+
npm pack --dry-run
|
|
278
|
+
|
|
279
|
+
# 3. Publish
|
|
280
|
+
npm publish --access public
|
|
281
|
+
|
|
282
|
+
# 4. Verify
|
|
283
|
+
npx create-odoo-module --version
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Contributing
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
git clone https://github.com/Brah-Timo/create-odoo-module.git
|
|
292
|
+
cd create-odoo-module
|
|
293
|
+
npm install
|
|
294
|
+
npm test
|
|
295
|
+
npm link # Use locally: npx create-odoo-module
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
MIT — see [LICENSE](LICENSE).
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
<p align="center">
|
|
307
|
+
Made with ♥ for the Odoo developer community<br>
|
|
308
|
+
<a href="https://create-odoo-module.dev">create-odoo-module.dev</a>
|
|
309
|
+
</p>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
// ─── Node version check ───────────────────────────────────────────────────────
|
|
6
|
+
const [major] = process.versions.node.split('.').map(Number);
|
|
7
|
+
if (major < 18) {
|
|
8
|
+
console.error(
|
|
9
|
+
`\n ✗ create-odoo-module requires Node.js 18 or higher.\n` +
|
|
10
|
+
` Current version: ${process.version}\n` +
|
|
11
|
+
` Download: https://nodejs.org\n`
|
|
12
|
+
);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ─── Imports ─────────────────────────────────────────────────────────────────
|
|
17
|
+
const { Command } = require('commander');
|
|
18
|
+
const chalk = require('chalk');
|
|
19
|
+
const gradient = require('gradient-string');
|
|
20
|
+
const boxen = require('boxen');
|
|
21
|
+
const { updateNotifier } = require('update-notifier');
|
|
22
|
+
const pkg = require('../package.json');
|
|
23
|
+
const { runCLI } = require('../src/cli/index');
|
|
24
|
+
|
|
25
|
+
// ─── Update notifier (non-blocking) ─────────────────────────────────────────
|
|
26
|
+
try {
|
|
27
|
+
const notifier = updateNotifier({ pkg, updateCheckInterval: 1000 * 60 * 60 * 24 });
|
|
28
|
+
if (notifier.update) {
|
|
29
|
+
console.log(
|
|
30
|
+
boxen(
|
|
31
|
+
chalk.yellow('Update available!') +
|
|
32
|
+
` ${chalk.dim(pkg.version)} → ${chalk.green(notifier.update.latest)}\n` +
|
|
33
|
+
chalk.cyan(`npm install -g ${pkg.name}@latest`),
|
|
34
|
+
{ padding: 1, margin: 1, borderStyle: 'round', borderColor: 'yellow' }
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
} catch (_) { /* update-notifier is optional */ }
|
|
39
|
+
|
|
40
|
+
// ─── Banner ───────────────────────────────────────────────────────────────────
|
|
41
|
+
const banner = gradient(['#875A7B', '#00A09D'])(
|
|
42
|
+
`
|
|
43
|
+
██████╗██████╗ ███████╗ █████╗ ████████╗███████╗
|
|
44
|
+
██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██╔════╝
|
|
45
|
+
██║ ██████╔╝█████╗ ███████║ ██║ █████╗
|
|
46
|
+
██║ ██╔══██╗██╔══╝ ██╔══██║ ██║ ██╔══╝
|
|
47
|
+
╚██████╗██║ ██║███████╗██║ ██║ ██║ ███████╗
|
|
48
|
+
╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝`
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
console.log(banner);
|
|
52
|
+
console.log(
|
|
53
|
+
boxen(
|
|
54
|
+
chalk.bold.white('create-odoo-module') +
|
|
55
|
+
chalk.dim(` v${pkg.version}`) + '\n' +
|
|
56
|
+
chalk.cyan('Next.js for Odoo') +
|
|
57
|
+
chalk.dim(' — One command. Full-stack ERP + Flutter app.'),
|
|
58
|
+
{
|
|
59
|
+
padding: { top: 0, bottom: 0, left: 2, right: 2 },
|
|
60
|
+
margin: { top: 0, bottom: 1, left: 0, right: 0 },
|
|
61
|
+
borderStyle: 'round',
|
|
62
|
+
borderColor: '#875A7B',
|
|
63
|
+
textAlignment: 'center'
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// ─── CLI Program ──────────────────────────────────────────────────────────────
|
|
69
|
+
const program = new Command();
|
|
70
|
+
|
|
71
|
+
program
|
|
72
|
+
.name('create-odoo-module')
|
|
73
|
+
.description('Generate a full Odoo module + Flutter app in seconds')
|
|
74
|
+
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
75
|
+
.helpOption('-h, --help', 'Display help for command');
|
|
76
|
+
|
|
77
|
+
// ─── Main command: create ─────────────────────────────────────────────────────
|
|
78
|
+
program
|
|
79
|
+
.argument('[module-name]', 'Name of your Odoo module (e.g. fleet-manager)')
|
|
80
|
+
.option('--with-api', 'Include REST API controllers', false)
|
|
81
|
+
.option('--with-ui', 'Include Flutter mobile app', false)
|
|
82
|
+
.option('--with-tests', 'Include Python + Dart test files', false)
|
|
83
|
+
.option('--with-reports', 'Include QWeb PDF reports', false)
|
|
84
|
+
.option('--with-owl', 'Include OWL JavaScript components', false)
|
|
85
|
+
.option('--with-wizard', 'Include wizard (transient model)', false)
|
|
86
|
+
.option('--with-docker', 'Include Docker Compose dev environment', true)
|
|
87
|
+
.option('--with-ci', 'Include GitHub Actions CI/CD pipeline', false)
|
|
88
|
+
.option('--odoo-version <ver>', 'Target Odoo version (16 | 17 | 18)', '17')
|
|
89
|
+
.option('--template <name>', 'Use a Pro template (fleet/hr/inventory/pos/crm)')
|
|
90
|
+
.option('--pro-key <key>', 'Pro license key for premium templates')
|
|
91
|
+
.option('--author <name>', 'Module author name', 'Your Company')
|
|
92
|
+
.option('--website <url>', 'Author website', 'https://yourcompany.com')
|
|
93
|
+
.option('--category <cat>', 'Odoo app category', 'Custom')
|
|
94
|
+
.option('--depends <modules>', 'Extra Odoo depends (comma separated)', '')
|
|
95
|
+
.option('--no-interactive', 'Skip all interactive prompts (use flags only)')
|
|
96
|
+
.option('--no-git', 'Skip git init in generated project')
|
|
97
|
+
.option('--verbose', 'Show verbose output', false)
|
|
98
|
+
.addHelpText('after', `
|
|
99
|
+
${chalk.bold('Examples:')}
|
|
100
|
+
${chalk.cyan('$ npx create-odoo-module')}
|
|
101
|
+
${chalk.cyan('$ npx create-odoo-module fleet-manager')}
|
|
102
|
+
${chalk.cyan('$ npx create-odoo-module fleet-manager --with-api --with-ui')}
|
|
103
|
+
${chalk.cyan('$ npx create-odoo-module hospital --with-api --with-ui --with-tests --odoo-version 18')}
|
|
104
|
+
${chalk.cyan('$ npx create-odoo-module pos-extend --template pos --pro-key YOUR_KEY')}
|
|
105
|
+
|
|
106
|
+
${chalk.bold('Pro Templates:')}
|
|
107
|
+
${chalk.yellow('fleet')} Fleet Management with vehicle tracking
|
|
108
|
+
${chalk.yellow('hr')} Human Resources with payroll
|
|
109
|
+
${chalk.yellow('inventory')} Inventory with barcode scanner
|
|
110
|
+
${chalk.yellow('pos')} Point of Sale extension
|
|
111
|
+
${chalk.yellow('crm')} CRM with pipeline dashboard
|
|
112
|
+
|
|
113
|
+
${chalk.bold('Documentation:')}
|
|
114
|
+
${chalk.underline('https://create-odoo-module.dev/docs')}
|
|
115
|
+
`)
|
|
116
|
+
.action(async (moduleName, options) => {
|
|
117
|
+
try {
|
|
118
|
+
await runCLI(moduleName, options);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
if (options.verbose) {
|
|
121
|
+
console.error(chalk.red('\n✗ Fatal error:'), err);
|
|
122
|
+
} else {
|
|
123
|
+
console.error(chalk.red(`\n✗ ${err.message}`));
|
|
124
|
+
console.error(chalk.dim(' Run with --verbose for full error details'));
|
|
125
|
+
}
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// ─── list command ─────────────────────────────────────────────────────────────
|
|
131
|
+
program
|
|
132
|
+
.command('list')
|
|
133
|
+
.description('List all available Pro templates')
|
|
134
|
+
.action(() => {
|
|
135
|
+
const { listTemplates } = require('../src/cli/index');
|
|
136
|
+
listTemplates();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// ─── upgrade command ──────────────────────────────────────────────────────────
|
|
140
|
+
program
|
|
141
|
+
.command('upgrade <module-path>')
|
|
142
|
+
.description('Upgrade an existing create-odoo-module project')
|
|
143
|
+
.action(async (modulePath) => {
|
|
144
|
+
console.log(chalk.yellow(`\n⚠ upgrade command coming in v1.1.0\n`));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
program.parse(process.argv);
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-odoo-module",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Next.js for Odoo. One command. Full-stack ERP + Flutter app in seconds.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-odoo-module": "bin/create-odoo-module.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "./src/cli/index.js",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"odoo",
|
|
11
|
+
"flutter",
|
|
12
|
+
"dart",
|
|
13
|
+
"cli",
|
|
14
|
+
"scaffold",
|
|
15
|
+
"generator",
|
|
16
|
+
"erp",
|
|
17
|
+
"module",
|
|
18
|
+
"create",
|
|
19
|
+
"boilerplate",
|
|
20
|
+
"odoo-module",
|
|
21
|
+
"odoo-generator",
|
|
22
|
+
"odoo-scaffold",
|
|
23
|
+
"odoo-flutter",
|
|
24
|
+
"odoo-rest-api"
|
|
25
|
+
],
|
|
26
|
+
"author": "create-odoo-module <contact@create-odoo-module.dev>",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"homepage": "https://create-odoo-module.dev",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/Brah-Timo/create-odoo-module.git"
|
|
32
|
+
},
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/Brah-Timo/create-odoo-module/issues"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"bin/",
|
|
41
|
+
"src/",
|
|
42
|
+
"README.md",
|
|
43
|
+
"CHANGELOG.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"axios": "^1.6.0",
|
|
48
|
+
"boxen": "^5.1.2",
|
|
49
|
+
"chalk": "^4.1.2",
|
|
50
|
+
"commander": "^12.0.0",
|
|
51
|
+
"ejs": "^3.1.9",
|
|
52
|
+
"execa": "^8.0.1",
|
|
53
|
+
"figures": "^3.2.0",
|
|
54
|
+
"fs-extra": "^11.2.0",
|
|
55
|
+
"gradient-string": "^2.0.2",
|
|
56
|
+
"inquirer": "^9.2.0",
|
|
57
|
+
"ora": "^5.4.1",
|
|
58
|
+
"semver": "^7.6.0",
|
|
59
|
+
"update-notifier": "^5.1.0",
|
|
60
|
+
"validate-npm-package-name": "^5.0.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/node": "^20.0.0",
|
|
64
|
+
"eslint": "^8.57.0",
|
|
65
|
+
"jest": "^29.7.0"
|
|
66
|
+
},
|
|
67
|
+
"scripts": {
|
|
68
|
+
"test": "jest --coverage",
|
|
69
|
+
"test:watch": "jest --watch",
|
|
70
|
+
"lint": "eslint src/ bin/ --fix",
|
|
71
|
+
"prepublishOnly": "npm test",
|
|
72
|
+
"link": "npm link",
|
|
73
|
+
"start": "node bin/create-odoo-module.js"
|
|
74
|
+
},
|
|
75
|
+
"jest": {
|
|
76
|
+
"testEnvironment": "node",
|
|
77
|
+
"testMatch": [
|
|
78
|
+
"**/tests/**/*.test.js"
|
|
79
|
+
],
|
|
80
|
+
"collectCoverageFrom": [
|
|
81
|
+
"src/**/*.js"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parse a comma-separated list of extra Odoo depends
|
|
5
|
+
* e.g. "sale_management,account" → ['sale_management', 'account']
|
|
6
|
+
*/
|
|
7
|
+
function parseExtraDepends(dependsString) {
|
|
8
|
+
if (!dependsString) return [];
|
|
9
|
+
return dependsString
|
|
10
|
+
.split(',')
|
|
11
|
+
.map(d => d.trim())
|
|
12
|
+
.filter(d => d.length > 0 && /^[a-z][a-z0-9_]*$/.test(d));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Parse Odoo version string, normalise to '16'|'17'|'18'
|
|
17
|
+
*/
|
|
18
|
+
function parseOdooVersion(version) {
|
|
19
|
+
if (!version) return '17';
|
|
20
|
+
const str = String(version);
|
|
21
|
+
if (str.startsWith('16')) return '16';
|
|
22
|
+
if (str.startsWith('17')) return '17';
|
|
23
|
+
if (str.startsWith('18')) return '18';
|
|
24
|
+
return '17'; // fallback
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parse a boolean flag that may come as string 'true'/'false'
|
|
29
|
+
*/
|
|
30
|
+
function parseBool(value, defaultVal = false) {
|
|
31
|
+
if (value === true || value === 'true') return true;
|
|
32
|
+
if (value === false || value === 'false') return false;
|
|
33
|
+
return defaultVal;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { parseExtraDepends, parseOdooVersion, parseBool };
|