domain-driver 0.0.4 → 0.0.5

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/README.md CHANGED
@@ -13,47 +13,182 @@ npm install -g domain-driver
13
13
  Or use without installing:
14
14
 
15
15
  ```bash
16
- npx domain-driver make:feature <name>
16
+ npx domain-driver make:feature <n>
17
17
  ```
18
18
 
19
19
  ---
20
20
 
21
- ## Usage
21
+ ## Commands
22
+
23
+ ### `make:feature`
24
+
25
+ Scaffold a full feature folder structure.
26
+
27
+ ```bash
28
+ domain-driver make:feature <n>
29
+ domain-driver make:feature <n> -a
30
+ ```
31
+
32
+ The `-a` flag scaffolds all files inside each folder automatically.
33
+
34
+ ```bash
35
+ domain-driver make:feature coffee-type # folders + .gitkeep only
36
+ domain-driver make:feature coffee-type -a # folders + all files
37
+ ```
38
+
39
+ ---
40
+
41
+ ### `make:component`
42
+
43
+ Scaffold a component inside an existing feature. Defaults to `client` if no type is specified.
44
+
45
+ ```bash
46
+ domain-driver make:component <feature> <n>
47
+ domain-driver make:component <feature> <n> client
48
+ domain-driver make:component <feature> <n> server
49
+ ```
50
+
51
+ ```bash
52
+ domain-driver make:component coffee-type CoffeeTypeList
53
+ domain-driver make:component coffee-type CoffeeTypeForm client
54
+ domain-driver make:component coffee-type CoffeeTypeCard server
55
+ ```
56
+
57
+ ---
58
+
59
+ ### `make:container`
60
+
61
+ Scaffold a smart container component inside an existing feature.
62
+
63
+ ```bash
64
+ domain-driver make:container <feature> <n>
65
+ ```
66
+
67
+ ```bash
68
+ domain-driver make:container coffee-type CoffeeTypeContainer
69
+ ```
70
+
71
+ ---
72
+
73
+ ### `make:hook`
74
+
75
+ Scaffold a custom hook inside an existing feature.
76
+
77
+ ```bash
78
+ domain-driver make:hook <feature> <n>
79
+ ```
80
+
81
+ ```bash
82
+ domain-driver make:hook coffee-type useCoffeeType
83
+ ```
84
+
85
+ ---
86
+
87
+ ### `make:service`
88
+
89
+ Scaffold a set of single-responsibility service files inside an existing feature.
90
+
91
+ ```bash
92
+ domain-driver make:service <feature> <n>
93
+ ```
22
94
 
23
95
  ```bash
24
- domain-driver make:feature <feature-name>
96
+ domain-driver make:service coffee-type CoffeeType
97
+ ```
98
+
99
+ Generates:
100
+
25
101
  ```
102
+ app/coffee-type/services/
103
+ ├── ListCoffeeType.service.ts
104
+ ├── ShowCoffeeType.service.ts
105
+ ├── CreateCoffeeType.service.ts
106
+ ├── UpdateCoffeeType.service.ts
107
+ └── DeleteCoffeeType.service.ts
108
+ ```
109
+
110
+ ---
111
+
112
+ ### `make:repository`
113
+
114
+ Scaffold a set of single-responsibility repository files inside an existing feature.
26
115
 
27
- ### Examples
116
+ ```bash
117
+ domain-driver make:repository <feature> <n>
118
+ ```
28
119
 
29
120
  ```bash
30
- domain-driver make:feature api-key
31
- domain-driver make:feature user-profile
32
- domain-driver make:feature payment
121
+ domain-driver make:repository coffee-type CoffeeType
122
+ ```
123
+
124
+ Generates:
125
+
126
+ ```
127
+ app/coffee-type/repositories/
128
+ ├── ListCoffeeType.repository.ts
129
+ ├── ShowCoffeeType.repository.ts
130
+ ├── CreateCoffeeType.repository.ts
131
+ ├── UpdateCoffeeType.repository.ts
132
+ └── DeleteCoffeeType.repository.ts
33
133
  ```
34
134
 
35
135
  ---
36
136
 
37
- ## What it generates
137
+ ### `make:schema`
138
+
139
+ Scaffold Zod schemas for create and update operations inside an existing feature.
140
+
141
+ ```bash
142
+ domain-driver make:schema <feature> <n>
143
+ ```
144
+
145
+ ```bash
146
+ domain-driver make:schema coffee-type CoffeeType
147
+ ```
38
148
 
39
- Running `domain-driver make:feature api-key` creates the following structure inside your Next.js `app/` directory:
149
+ Generates:
150
+
151
+ ```
152
+ app/coffee-type/schemas/
153
+ ├── CreateCoffeeType.schema.ts
154
+ └── UpdateCoffeeType.schema.ts
155
+ ```
156
+
157
+ ---
158
+
159
+ ## What `make:feature -a` generates
160
+
161
+ Running `domain-driver make:feature coffee-type -a` creates the full structure:
40
162
 
41
163
  ```
42
164
  app/
43
- └── api-key/
165
+ └── coffee-type/
44
166
  ├── components/
45
- │ ├── server/ # React Server Components
46
- │ └── client/ # Client components ('use client')
47
- ├── containers/ # Smart components — wire hooks → UI
48
- ├── hooks/ # Feature-specific hooks (useApiKey, etc.)
49
- ├── services/ # Business logic and transformations
50
- ├── repositories/ # Data access layer (fetch/axios calls)
51
- ├── schemas/ # Zod schemas for forms and API validation
52
- └── page.tsx # Next.js page entry point
167
+ │ ├── server/
168
+ │ └── client/
169
+ │ └── CoffeeType.tsx
170
+ ├── containers/
171
+ │ └── CoffeeTypeContainer.tsx
172
+ ├── hooks/
173
+ │ └── useCoffeeType.ts
174
+ ├── services/
175
+ │ ├── ListCoffeeType.service.ts
176
+ │ ├── ShowCoffeeType.service.ts
177
+ │ ├── CreateCoffeeType.service.ts
178
+ │ ├── UpdateCoffeeType.service.ts
179
+ │ └── DeleteCoffeeType.service.ts
180
+ ├── repositories/
181
+ │ ├── ListCoffeeType.repository.ts
182
+ │ ├── ShowCoffeeType.repository.ts
183
+ │ ├── CreateCoffeeType.repository.ts
184
+ │ ├── UpdateCoffeeType.repository.ts
185
+ │ └── DeleteCoffeeType.repository.ts
186
+ ├── schemas/
187
+ │ ├── CreateCoffeeType.schema.ts
188
+ │ └── UpdateCoffeeType.schema.ts
189
+ └── page.tsx
53
190
  ```
54
191
 
55
- Each folder includes a `.gitkeep` file so empty directories are tracked in Git.
56
-
57
192
  ---
58
193
 
59
194
  ## Philosophy
@@ -67,22 +202,27 @@ The layer responsibilities are:
67
202
  - **hooks** — React state and side effects, calls services
68
203
  - **containers** — wire hooks into UI, no direct data fetching
69
204
  - **components** — pure presentational UI, no data dependencies
70
- - **schemas** — Zod validation for both forms and API responses
205
+ - **schemas** — Zod validation for create and update operations
71
206
 
72
207
  ---
73
208
 
74
209
  ## Requirements
75
210
 
76
211
  - Node.js 18+
77
- - A Next.js project with an `app/` directory (App Router)
78
212
 
79
213
  ---
80
214
 
215
+ ## Framework Support
216
+
217
+ This tool is optimised for **Next.js App Router** projects. All files are scaffolded into the `app/` directory following Next.js conventions (`page.tsx`, server/client component separation, etc.).
218
+
219
+ If no `app/` directory exists, it will be created automatically. This means the tool can also be used in any project where an `app/<feature>` folder structure makes sense.
220
+
81
221
  ## Local Development
82
222
 
83
223
  ```bash
84
224
  # Clone the repo
85
- git clone https://github.com/yourname/domain-driver
225
+ git clone https://github.com/IsaacHatilima/domain-driver
86
226
  cd domain-driver
87
227
 
88
228
  # Install dependencies
@@ -96,17 +236,22 @@ npm link
96
236
 
97
237
  # Test it
98
238
  domain-driver make:feature test-feature
239
+ domain-driver make:feature test-feature -a
99
240
  ```
100
241
 
101
242
  ---
102
243
 
103
244
  ## Roadmap
104
245
 
105
- - [ ] `make:component` — scaffold a single component
106
- - [ ] `make:hook` — scaffold a custom hook
107
- - [ ] `make:service` — scaffold a service
108
- - [ ] Framework detection auto-adapt structure for Laravel, Go, etc.
109
- - [ ] Interactive mode prompt for feature name if not provided
246
+ - [x] `make:feature` — scaffold feature folder structure
247
+ - [x] `make:feature -a` — scaffold feature with all files
248
+ - [x] `make:component` — scaffold a component
249
+ - [x] `make:container`scaffold a container
250
+ - [x] `make:hook`scaffold a custom hook
251
+ - [x] `make:service` — scaffold single-responsibility services
252
+ - [x] `make:repository` — scaffold single-responsibility repositories
253
+ - [x] `make:schema` — scaffold Zod schemas
254
+ - [ ] Interactive mode — prompt for name if not provided
110
255
  - [ ] Config file — customize folder structure per project
111
256
 
112
257
  ---
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeComponent = makeComponent;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function renderComponent(name, type) {
40
+ const directive = type === 'client' ? "'use client';\n\n" : '';
41
+ return `${directive}export default function ${name}() {
42
+ return (
43
+ <div>
44
+ <h1>${name}</h1>
45
+ </div>
46
+ );
47
+ }
48
+ `;
49
+ }
50
+ function makeComponent(feature, name, type = 'client') {
51
+ const base = path.join(process.cwd(), 'app', feature, 'components', type);
52
+ if (!fs.existsSync(base)) {
53
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
54
+ process.exit(1);
55
+ }
56
+ const filePath = path.join(base, `${name}.tsx`);
57
+ if (fs.existsSync(filePath)) {
58
+ console.error(`❌ Component "${name}" already exists at ${filePath}`);
59
+ process.exit(1);
60
+ }
61
+ fs.writeFileSync(filePath, renderComponent(name, type));
62
+ console.log(`✅ Component "${name}" created at ${filePath}`);
63
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeContainer = makeContainer;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function renderContainer(name) {
40
+ return `'use client';
41
+
42
+ interface Props {}
43
+
44
+ export default function ${name}({ }: Props) {
45
+ return (
46
+ <div>
47
+ <h1>${name}</h1>
48
+ </div>
49
+ );
50
+ }
51
+ `;
52
+ }
53
+ function makeContainer(feature, name) {
54
+ const base = path.join(process.cwd(), 'app', feature, 'containers');
55
+ if (!fs.existsSync(base)) {
56
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
57
+ process.exit(1);
58
+ }
59
+ const filePath = path.join(base, `${name}.tsx`);
60
+ if (fs.existsSync(filePath)) {
61
+ console.error(`❌ Container "${name}" already exists at ${filePath}`);
62
+ process.exit(1);
63
+ }
64
+ fs.writeFileSync(filePath, renderContainer(name));
65
+ console.log(`✅ Container "${name}" created at ${filePath}`);
66
+ }
@@ -36,6 +36,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.makeFeature = makeFeature;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const component_1 = require("./component");
40
+ const hook_1 = require("./hook");
41
+ const service_1 = require("./service");
42
+ const repository_1 = require("./repository");
43
+ const schema_1 = require("./schema");
44
+ const container_1 = require("./container");
39
45
  const FEATURE_DIRS = [
40
46
  'components/server',
41
47
  'components/client',
@@ -45,11 +51,14 @@ const FEATURE_DIRS = [
45
51
  'repositories',
46
52
  'schemas',
47
53
  ];
48
- function renderTemplate(name) {
49
- const componentName = name
54
+ function toPascalCase(name) {
55
+ return name
50
56
  .split('-')
51
57
  .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
52
58
  .join('');
59
+ }
60
+ function renderPage(name) {
61
+ const componentName = toPascalCase(name);
53
62
  return `export default function ${componentName}Page() {
54
63
  return (
55
64
  <div>
@@ -59,13 +68,28 @@ function renderTemplate(name) {
59
68
  }
60
69
  `;
61
70
  }
62
- async function makeFeature(name) {
71
+ async function makeFeature(name, all = false) {
63
72
  const base = path.join(process.cwd(), 'app', name);
73
+ const pascalName = toPascalCase(name);
74
+ if (fs.existsSync(base)) {
75
+ console.error(`❌ Feature "${name}" already exists at ${base}`);
76
+ process.exit(1);
77
+ }
64
78
  for (const dir of FEATURE_DIRS) {
65
79
  fs.mkdirSync(path.join(base, dir), { recursive: true });
66
- fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
80
+ if (!all) {
81
+ fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
82
+ }
67
83
  }
68
- const page = renderTemplate(name);
69
- fs.writeFileSync(path.join(base, 'page.tsx'), page);
84
+ fs.writeFileSync(path.join(base, 'page.tsx'), renderPage(name));
70
85
  console.log(`✅ Feature "${name}" scaffolded at ${base}`);
86
+ if (all) {
87
+ (0, component_1.makeComponent)(name, pascalName, 'client');
88
+ (0, container_1.makeContainer)(name, `${pascalName}Container`);
89
+ (0, hook_1.makeHook)(name, `use${pascalName}`);
90
+ (0, service_1.makeService)(name, pascalName);
91
+ (0, repository_1.makeRepository)(name, `${pascalName}Repository`);
92
+ (0, schema_1.makeSchema)(name, `${pascalName}Schema`);
93
+ console.log(`✅ All files scaffolded for "${name}"`);
94
+ }
71
95
  }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeHook = makeHook;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function renderHook(name) {
40
+ return `import { useState } from 'react';
41
+
42
+ export function ${name}() {
43
+ const [data, setData] = useState(null);
44
+
45
+ return { data };
46
+ }
47
+ `;
48
+ }
49
+ function makeHook(feature, name) {
50
+ const base = path.join(process.cwd(), 'app', feature, 'hooks');
51
+ if (!fs.existsSync(base)) {
52
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
53
+ process.exit(1);
54
+ }
55
+ const filePath = path.join(base, `${name}.ts`);
56
+ if (fs.existsSync(filePath)) {
57
+ console.error(`❌ Hook "${name}" already exists at ${filePath}`);
58
+ process.exit(1);
59
+ }
60
+ fs.writeFileSync(filePath, renderHook(name));
61
+ console.log(`✅ Hook "${name}" created at ${filePath}`);
62
+ }
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeRepository = makeRepository;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const REPOSITORY_ACTIONS = ['List', 'Create', 'Update', 'Delete', 'Show'];
40
+ function renderRepository(action, name, feature) {
41
+ switch (action) {
42
+ case 'List':
43
+ return `export class List${name}Repository {
44
+ async handle() {
45
+ const response = await fetch('/api/${feature}');
46
+ return response.json();
47
+ }
48
+ }
49
+ `;
50
+ case 'Show':
51
+ return `export class Show${name}Repository {
52
+ async handle(id: string) {
53
+ const response = await fetch(\`/api/${feature}/\${id}\`);
54
+ return response.json();
55
+ }
56
+ }
57
+ `;
58
+ case 'Create':
59
+ return `export class Create${name}Repository {
60
+ async handle(data: unknown) {
61
+ const response = await fetch('/api/${feature}', {
62
+ method: 'POST',
63
+ body: JSON.stringify(data),
64
+ });
65
+ return response.json();
66
+ }
67
+ }
68
+ `;
69
+ case 'Update':
70
+ return `export class Update${name}Repository {
71
+ async handle(id: string, data: unknown) {
72
+ const response = await fetch(\`/api/${feature}/\${id}\`, {
73
+ method: 'PUT',
74
+ body: JSON.stringify(data),
75
+ });
76
+ return response.json();
77
+ }
78
+ }
79
+ `;
80
+ case 'Delete':
81
+ return `export class Delete${name}Repository {
82
+ async handle(id: string) {
83
+ const response = await fetch(\`/api/${feature}/\${id}\`, {
84
+ method: 'DELETE',
85
+ });
86
+ return response.json();
87
+ }
88
+ }
89
+ `;
90
+ }
91
+ }
92
+ function makeRepository(feature, name) {
93
+ const base = path.join(process.cwd(), 'app', feature, 'repositories');
94
+ if (!fs.existsSync(base)) {
95
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
96
+ process.exit(1);
97
+ }
98
+ for (const action of REPOSITORY_ACTIONS) {
99
+ const filePath = path.join(base, `${action}${name}.repository.ts`);
100
+ if (fs.existsSync(filePath)) {
101
+ console.warn(`⚠️ Skipping "${action}${name}.repository.ts" — already exists`);
102
+ continue;
103
+ }
104
+ fs.writeFileSync(filePath, renderRepository(action, name, feature));
105
+ }
106
+ console.log(`✅ Repositories for "${name}" created at ${base}`);
107
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeSchema = makeSchema;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const SCHEMA_ACTIONS = ['Create', 'Update'];
40
+ function renderSchema(action, name) {
41
+ switch (action) {
42
+ case 'Create':
43
+ return `import { z } from 'zod';
44
+
45
+ export const Create${name}Schema = z.object({
46
+ // add create fields here
47
+ });
48
+
49
+ export type Create${name} = z.infer<typeof Create${name}Schema>;
50
+ `;
51
+ case 'Update':
52
+ return `import { z } from 'zod';
53
+
54
+ export const Update${name}Schema = z.object({
55
+ id: z.string(),
56
+ // add update fields here
57
+ });
58
+
59
+ export type Update${name} = z.infer<typeof Update${name}Schema>;
60
+ `;
61
+ }
62
+ }
63
+ function makeSchema(feature, name) {
64
+ const base = path.join(process.cwd(), 'app', feature, 'schemas');
65
+ if (!fs.existsSync(base)) {
66
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
67
+ process.exit(1);
68
+ }
69
+ for (const action of SCHEMA_ACTIONS) {
70
+ const filePath = path.join(base, `${action}${name}.schema.ts`);
71
+ if (fs.existsSync(filePath)) {
72
+ console.warn(`⚠️ Skipping "${action}${name}.schema.ts" — already exists`);
73
+ continue;
74
+ }
75
+ fs.writeFileSync(filePath, renderSchema(action, name));
76
+ }
77
+ console.log(`✅ Schemas for "${name}" created at ${base}`);
78
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.makeService = makeService;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const SERVICE_ACTIONS = ['List', 'Create', 'Update', 'Delete', 'Show'];
40
+ function renderService(action, name) {
41
+ switch (action) {
42
+ case 'List':
43
+ return `export class List${name}Service {
44
+ async handle() {
45
+ // fetch all ${name}
46
+ }
47
+ }
48
+ `;
49
+ case 'Show':
50
+ return `export class Show${name}Service {
51
+ async handle(id: string) {
52
+ // fetch single ${name}
53
+ }
54
+ }
55
+ `;
56
+ case 'Create':
57
+ return `export class Create${name}Service {
58
+ async handle(data: unknown) {
59
+ // create ${name}
60
+ }
61
+ }
62
+ `;
63
+ case 'Update':
64
+ return `export class Update${name}Service {
65
+ async handle(id: string, data: unknown) {
66
+ // update ${name}
67
+ }
68
+ }
69
+ `;
70
+ case 'Delete':
71
+ return `export class Delete${name}Service {
72
+ async handle(id: string) {
73
+ // delete ${name}
74
+ }
75
+ }
76
+ `;
77
+ }
78
+ }
79
+ function makeService(feature, name) {
80
+ const base = path.join(process.cwd(), 'app', feature, 'services');
81
+ if (!fs.existsSync(base)) {
82
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
83
+ process.exit(1);
84
+ }
85
+ for (const action of SERVICE_ACTIONS) {
86
+ const filePath = path.join(base, `${action}${name}.service.ts`);
87
+ if (fs.existsSync(filePath)) {
88
+ console.warn(`⚠️ Skipping "${action}${name}.service.ts" — already exists`);
89
+ continue;
90
+ }
91
+ fs.writeFileSync(filePath, renderService(action, name));
92
+ }
93
+ console.log(`✅ Services for "${name}" created at ${base}`);
94
+ }
package/dist/index.js CHANGED
@@ -2,15 +2,66 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const feature_1 = require("./commands/feature");
5
- const [, , command, name] = process.argv;
6
- if (!command || !name) {
7
- console.error('Usage: domain-driver make:feature <name>');
5
+ const component_1 = require("./commands/component");
6
+ const hook_1 = require("./commands/hook");
7
+ const service_1 = require("./commands/service");
8
+ const schema_1 = require("./commands/schema");
9
+ const repository_1 = require("./commands/repository");
10
+ const container_1 = require("./commands/container");
11
+ const [, , command, feature, name] = process.argv;
12
+ if (!command || !feature) {
13
+ console.error('Usage: domain-driver <command> [options]');
8
14
  process.exit(1);
9
15
  }
10
- if (command === 'make:feature') {
11
- (0, feature_1.makeFeature)(name);
12
- }
13
- else {
14
- console.error(`Unknown command: ${command}`);
15
- process.exit(1);
16
+ switch (command) {
17
+ case 'make:feature':
18
+ const all = process.argv.includes('-a') || process.argv.includes('-A');
19
+ (0, feature_1.makeFeature)(feature, all).then(() => { });
20
+ break;
21
+ case 'make:component':
22
+ if (!name) {
23
+ console.error('Usage: domain-driver make:component <feature> <name> [client|server]');
24
+ process.exit(1);
25
+ }
26
+ const type = process.argv[5] || 'client';
27
+ (0, component_1.makeComponent)(feature, name, type);
28
+ break;
29
+ case 'make:hook':
30
+ if (!name) {
31
+ console.error('Usage: domain-driver make:hook <feature> <name>');
32
+ process.exit(1);
33
+ }
34
+ (0, hook_1.makeHook)(feature, name);
35
+ break;
36
+ case 'make:service':
37
+ if (!name) {
38
+ console.error('Usage: domain-driver make:service <feature> <name>');
39
+ process.exit(1);
40
+ }
41
+ (0, service_1.makeService)(feature, name);
42
+ break;
43
+ case 'make:schema':
44
+ if (!name) {
45
+ console.error('Usage: domain-driver make:schema <feature> <name>');
46
+ process.exit(1);
47
+ }
48
+ (0, schema_1.makeSchema)(feature, name);
49
+ break;
50
+ case 'make:repository':
51
+ if (!name) {
52
+ console.error('Usage: domain-driver make:repository <feature> <name>');
53
+ process.exit(1);
54
+ }
55
+ (0, repository_1.makeRepository)(feature, name);
56
+ break;
57
+ case 'make:container':
58
+ if (!name) {
59
+ console.error('Usage: domain-driver make:container <feature> <name>');
60
+ process.exit(1);
61
+ }
62
+ (0, container_1.makeContainer)(feature, name);
63
+ break;
64
+ default:
65
+ console.error(`Unknown command: ${command}`);
66
+ process.exit(1);
16
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domain-driver",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -0,0 +1,36 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ type ComponentType = 'client' | 'server';
5
+
6
+ function renderComponent(name: string, type: ComponentType): string {
7
+ const directive = type === 'client' ? "'use client';\n\n" : '';
8
+
9
+ return `${directive}export default function ${name}() {
10
+ return (
11
+ <div>
12
+ <h1>${name}</h1>
13
+ </div>
14
+ );
15
+ }
16
+ `;
17
+ }
18
+
19
+ export function makeComponent(feature: string, name: string, type: ComponentType = 'client') {
20
+ const base = path.join(process.cwd(), 'app', feature, 'components', type);
21
+
22
+ if (!fs.existsSync(base)) {
23
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
24
+ process.exit(1);
25
+ }
26
+
27
+ const filePath = path.join(base, `${name}.tsx`);
28
+
29
+ if (fs.existsSync(filePath)) {
30
+ console.error(`❌ Component "${name}" already exists at ${filePath}`);
31
+ process.exit(1);
32
+ }
33
+
34
+ fs.writeFileSync(filePath, renderComponent(name, type));
35
+ console.log(`✅ Component "${name}" created at ${filePath}`);
36
+ }
@@ -0,0 +1,36 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ function renderContainer(name: string): string {
5
+ return `'use client';
6
+
7
+ interface Props {}
8
+
9
+ export default function ${name}({ }: Props) {
10
+ return (
11
+ <div>
12
+ <h1>${name}</h1>
13
+ </div>
14
+ );
15
+ }
16
+ `;
17
+ }
18
+
19
+ export function makeContainer(feature: string, name: string) {
20
+ const base = path.join(process.cwd(), 'app', feature, 'containers');
21
+
22
+ if (!fs.existsSync(base)) {
23
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
24
+ process.exit(1);
25
+ }
26
+
27
+ const filePath = path.join(base, `${name}.tsx`);
28
+
29
+ if (fs.existsSync(filePath)) {
30
+ console.error(`❌ Container "${name}" already exists at ${filePath}`);
31
+ process.exit(1);
32
+ }
33
+
34
+ fs.writeFileSync(filePath, renderContainer(name));
35
+ console.log(`✅ Container "${name}" created at ${filePath}`);
36
+ }
@@ -1,5 +1,11 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
+ import { makeComponent } from './component';
4
+ import { makeHook } from './hook';
5
+ import { makeService } from './service';
6
+ import { makeRepository } from './repository';
7
+ import { makeSchema } from './schema';
8
+ import { makeContainer } from './container';
3
9
 
4
10
  const FEATURE_DIRS = [
5
11
  'components/server',
@@ -11,12 +17,15 @@ const FEATURE_DIRS = [
11
17
  'schemas',
12
18
  ];
13
19
 
14
- function renderTemplate(name: string): string {
15
- const componentName = name
20
+ function toPascalCase(name: string): string {
21
+ return name
16
22
  .split('-')
17
23
  .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
18
24
  .join('');
25
+ }
19
26
 
27
+ function renderPage(name: string): string {
28
+ const componentName = toPascalCase(name);
20
29
  return `export default function ${componentName}Page() {
21
30
  return (
22
31
  <div>
@@ -27,16 +36,33 @@ function renderTemplate(name: string): string {
27
36
  `;
28
37
  }
29
38
 
30
- export async function makeFeature(name: string) {
39
+ export async function makeFeature(name: string, all: boolean = false) {
31
40
  const base = path.join(process.cwd(), 'app', name);
41
+ const pascalName = toPascalCase(name);
42
+
43
+ if (fs.existsSync(base)) {
44
+ console.error(`❌ Feature "${name}" already exists at ${base}`);
45
+ process.exit(1);
46
+ }
32
47
 
33
48
  for (const dir of FEATURE_DIRS) {
34
49
  fs.mkdirSync(path.join(base, dir), { recursive: true });
35
- fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
50
+ if (!all) {
51
+ fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
52
+ }
36
53
  }
37
54
 
38
- const page = renderTemplate(name);
39
- fs.writeFileSync(path.join(base, 'page.tsx'), page);
40
-
55
+ fs.writeFileSync(path.join(base, 'page.tsx'), renderPage(name));
41
56
  console.log(`✅ Feature "${name}" scaffolded at ${base}`);
57
+
58
+ if (all) {
59
+ makeComponent(name, pascalName, 'client');
60
+ makeContainer(name, `${pascalName}Container`);
61
+ makeHook(name, `use${pascalName}`);
62
+ makeService(name, pascalName);
63
+ makeRepository(name, `${pascalName}Repository`);
64
+ makeSchema(name, `${pascalName}Schema`);
65
+
66
+ console.log(`✅ All files scaffolded for "${name}"`);
67
+ }
42
68
  }
@@ -0,0 +1,32 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ function renderHook(name: string): string {
5
+ return `import { useState } from 'react';
6
+
7
+ export function ${name}() {
8
+ const [data, setData] = useState(null);
9
+
10
+ return { data };
11
+ }
12
+ `;
13
+ }
14
+
15
+ export function makeHook(feature: string, name: string) {
16
+ const base = path.join(process.cwd(), 'app', feature, 'hooks');
17
+
18
+ if (!fs.existsSync(base)) {
19
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
20
+ process.exit(1);
21
+ }
22
+
23
+ const filePath = path.join(base, `${name}.ts`);
24
+
25
+ if (fs.existsSync(filePath)) {
26
+ console.error(`❌ Hook "${name}" already exists at ${filePath}`);
27
+ process.exit(1);
28
+ }
29
+
30
+ fs.writeFileSync(filePath, renderHook(name));
31
+ console.log(`✅ Hook "${name}" created at ${filePath}`);
32
+ }
@@ -0,0 +1,81 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ type RepositoryAction = 'List' | 'Create' | 'Update' | 'Delete' | 'Show';
5
+
6
+ const REPOSITORY_ACTIONS: RepositoryAction[] = ['List', 'Create', 'Update', 'Delete', 'Show'];
7
+
8
+ function renderRepository(action: RepositoryAction, name: string, feature: string): string {
9
+ switch (action) {
10
+ case 'List':
11
+ return `export class List${name}Repository {
12
+ async handle() {
13
+ const response = await fetch('/api/${feature}');
14
+ return response.json();
15
+ }
16
+ }
17
+ `;
18
+ case 'Show':
19
+ return `export class Show${name}Repository {
20
+ async handle(id: string) {
21
+ const response = await fetch(\`/api/${feature}/\${id}\`);
22
+ return response.json();
23
+ }
24
+ }
25
+ `;
26
+ case 'Create':
27
+ return `export class Create${name}Repository {
28
+ async handle(data: unknown) {
29
+ const response = await fetch('/api/${feature}', {
30
+ method: 'POST',
31
+ body: JSON.stringify(data),
32
+ });
33
+ return response.json();
34
+ }
35
+ }
36
+ `;
37
+ case 'Update':
38
+ return `export class Update${name}Repository {
39
+ async handle(id: string, data: unknown) {
40
+ const response = await fetch(\`/api/${feature}/\${id}\`, {
41
+ method: 'PUT',
42
+ body: JSON.stringify(data),
43
+ });
44
+ return response.json();
45
+ }
46
+ }
47
+ `;
48
+ case 'Delete':
49
+ return `export class Delete${name}Repository {
50
+ async handle(id: string) {
51
+ const response = await fetch(\`/api/${feature}/\${id}\`, {
52
+ method: 'DELETE',
53
+ });
54
+ return response.json();
55
+ }
56
+ }
57
+ `;
58
+ }
59
+ }
60
+
61
+ export function makeRepository(feature: string, name: string) {
62
+ const base = path.join(process.cwd(), 'app', feature, 'repositories');
63
+
64
+ if (!fs.existsSync(base)) {
65
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
66
+ process.exit(1);
67
+ }
68
+
69
+ for (const action of REPOSITORY_ACTIONS) {
70
+ const filePath = path.join(base, `${action}${name}.repository.ts`);
71
+
72
+ if (fs.existsSync(filePath)) {
73
+ console.warn(`⚠️ Skipping "${action}${name}.repository.ts" — already exists`);
74
+ continue;
75
+ }
76
+
77
+ fs.writeFileSync(filePath, renderRepository(action, name, feature));
78
+ }
79
+
80
+ console.log(`✅ Repositories for "${name}" created at ${base}`);
81
+ }
@@ -0,0 +1,52 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ type SchemaAction = 'Create' | 'Update';
5
+
6
+ const SCHEMA_ACTIONS: SchemaAction[] = ['Create', 'Update'];
7
+
8
+ function renderSchema(action: SchemaAction, name: string): string {
9
+ switch (action) {
10
+ case 'Create':
11
+ return `import { z } from 'zod';
12
+
13
+ export const Create${name}Schema = z.object({
14
+ // add create fields here
15
+ });
16
+
17
+ export type Create${name} = z.infer<typeof Create${name}Schema>;
18
+ `;
19
+ case 'Update':
20
+ return `import { z } from 'zod';
21
+
22
+ export const Update${name}Schema = z.object({
23
+ id: z.string(),
24
+ // add update fields here
25
+ });
26
+
27
+ export type Update${name} = z.infer<typeof Update${name}Schema>;
28
+ `;
29
+ }
30
+ }
31
+
32
+ export function makeSchema(feature: string, name: string) {
33
+ const base = path.join(process.cwd(), 'app', feature, 'schemas');
34
+
35
+ if (!fs.existsSync(base)) {
36
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
37
+ process.exit(1);
38
+ }
39
+
40
+ for (const action of SCHEMA_ACTIONS) {
41
+ const filePath = path.join(base, `${action}${name}.schema.ts`);
42
+
43
+ if (fs.existsSync(filePath)) {
44
+ console.warn(`⚠️ Skipping "${action}${name}.schema.ts" — already exists`);
45
+ continue;
46
+ }
47
+
48
+ fs.writeFileSync(filePath, renderSchema(action, name));
49
+ }
50
+
51
+ console.log(`✅ Schemas for "${name}" created at ${base}`);
52
+ }
@@ -0,0 +1,68 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ type ServiceAction = 'List' | 'Create' | 'Update' | 'Delete' | 'Show';
5
+
6
+ const SERVICE_ACTIONS: ServiceAction[] = ['List', 'Create', 'Update', 'Delete', 'Show'];
7
+
8
+ function renderService(action: ServiceAction, name: string): string {
9
+ switch (action) {
10
+ case 'List':
11
+ return `export class List${name}Service {
12
+ async handle() {
13
+ // fetch all ${name}
14
+ }
15
+ }
16
+ `;
17
+ case 'Show':
18
+ return `export class Show${name}Service {
19
+ async handle(id: string) {
20
+ // fetch single ${name}
21
+ }
22
+ }
23
+ `;
24
+ case 'Create':
25
+ return `export class Create${name}Service {
26
+ async handle(data: unknown) {
27
+ // create ${name}
28
+ }
29
+ }
30
+ `;
31
+ case 'Update':
32
+ return `export class Update${name}Service {
33
+ async handle(id: string, data: unknown) {
34
+ // update ${name}
35
+ }
36
+ }
37
+ `;
38
+ case 'Delete':
39
+ return `export class Delete${name}Service {
40
+ async handle(id: string) {
41
+ // delete ${name}
42
+ }
43
+ }
44
+ `;
45
+ }
46
+ }
47
+
48
+ export function makeService(feature: string, name: string) {
49
+ const base = path.join(process.cwd(), 'app', feature, 'services');
50
+
51
+ if (!fs.existsSync(base)) {
52
+ console.error(`❌ Feature "${feature}" does not exist. Run make:feature ${feature} first.`);
53
+ process.exit(1);
54
+ }
55
+
56
+ for (const action of SERVICE_ACTIONS) {
57
+ const filePath = path.join(base, `${action}${name}.service.ts`);
58
+
59
+ if (fs.existsSync(filePath)) {
60
+ console.warn(`⚠️ Skipping "${action}${name}.service.ts" — already exists`);
61
+ continue;
62
+ }
63
+
64
+ fs.writeFileSync(filePath, renderService(action, name));
65
+ }
66
+
67
+ console.log(`✅ Services for "${name}" created at ${base}`);
68
+ }
package/src/index.ts CHANGED
@@ -1,16 +1,75 @@
1
1
  #!/usr/bin/env node
2
2
  import { makeFeature } from './commands/feature';
3
+ import { makeComponent } from './commands/component';
4
+ import { makeHook } from './commands/hook';
5
+ import { makeService } from './commands/service';
6
+ import { makeSchema } from './commands/schema';
7
+ import { makeRepository } from './commands/repository';
8
+ import { makeContainer } from './commands/container';
3
9
 
4
- const [,, command, name] = process.argv;
10
+ const [,, command, feature, name] = process.argv;
5
11
 
6
- if (!command || !name) {
7
- console.error('Usage: domain-driver make:feature <name>');
12
+ if (!command || !feature) {
13
+ console.error('Usage: domain-driver <command> [options]');
8
14
  process.exit(1);
9
15
  }
10
16
 
11
- if (command === 'make:feature') {
12
- makeFeature(name);
13
- } else {
14
- console.error(`Unknown command: ${command}`);
15
- process.exit(1);
17
+ switch (command) {
18
+ case 'make:feature':
19
+ const all = process.argv.includes('-a') || process.argv.includes('-A');
20
+ makeFeature(feature, all).then(() => {});
21
+ break;
22
+
23
+ case 'make:component':
24
+ if (!name) {
25
+ console.error('Usage: domain-driver make:component <feature> <name> [client|server]');
26
+ process.exit(1);
27
+ }
28
+ const type = (process.argv[5] as 'client' | 'server') || 'client';
29
+ makeComponent(feature, name, type);
30
+ break;
31
+
32
+ case 'make:hook':
33
+ if (!name) {
34
+ console.error('Usage: domain-driver make:hook <feature> <name>');
35
+ process.exit(1);
36
+ }
37
+ makeHook(feature, name);
38
+ break;
39
+
40
+ case 'make:service':
41
+ if (!name) {
42
+ console.error('Usage: domain-driver make:service <feature> <name>');
43
+ process.exit(1);
44
+ }
45
+ makeService(feature, name);
46
+ break;
47
+
48
+ case 'make:schema':
49
+ if (!name) {
50
+ console.error('Usage: domain-driver make:schema <feature> <name>');
51
+ process.exit(1);
52
+ }
53
+ makeSchema(feature, name);
54
+ break;
55
+
56
+ case 'make:repository':
57
+ if (!name) {
58
+ console.error('Usage: domain-driver make:repository <feature> <name>');
59
+ process.exit(1);
60
+ }
61
+ makeRepository(feature, name);
62
+ break;
63
+
64
+ case 'make:container':
65
+ if (!name) {
66
+ console.error('Usage: domain-driver make:container <feature> <name>');
67
+ process.exit(1);
68
+ }
69
+ makeContainer(feature, name);
70
+ break;
71
+
72
+ default:
73
+ console.error(`Unknown command: ${command}`);
74
+ process.exit(1);
16
75
  }