domain-driver 0.0.1

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.
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Ask2AgentMigrationStateService">
4
+ <option name="migrationStatus" value="COMPLETED" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
@@ -0,0 +1,5 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ </profile>
5
+ </component>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="JavaScriptLibraryMappings">
4
+ <includedPredefinedLibrary name="Node.js Core" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MaterialThemeProjectNewConfig">
4
+ <option name="metadata">
5
+ <MTProjectMetadataState>
6
+ <option name="userId" value="3f40c18c:19cdf0955d0:-7e51" />
7
+ </MTProjectMetadataState>
8
+ </option>
9
+ </component>
10
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/domain-driver.iml" filepath="$PROJECT_DIR$/.idea/domain-driver.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="SwiftToolchain">
4
+ <option name="toolchain" value="system-/usr/bin/swift" />
5
+ </component>
6
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # domain-driver 🚀
2
+
3
+ A CLI scaffolding tool for domain-driven development in Next.js. Generate feature folder structures instantly — like Laravel's `php artisan make` but for Next.js.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install -g domain-driver
11
+ ```
12
+
13
+ Or use without installing:
14
+
15
+ ```bash
16
+ npx domain-driver make:feature <name>
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Usage
22
+
23
+ ```bash
24
+ domain-driver make:feature <feature-name>
25
+ ```
26
+
27
+ ### Examples
28
+
29
+ ```bash
30
+ domain-driver make:feature api-key
31
+ domain-driver make:feature user-profile
32
+ domain-driver make:feature payment
33
+ ```
34
+
35
+ ---
36
+
37
+ ## What it generates
38
+
39
+ Running `domain-driver make:feature api-key` creates the following structure inside your Next.js `app/` directory:
40
+
41
+ ```
42
+ app/
43
+ └── api-key/
44
+ ├── 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
53
+ ```
54
+
55
+ Each folder includes a `.gitkeep` file so empty directories are tracked in Git.
56
+
57
+ ---
58
+
59
+ ## Philosophy
60
+
61
+ This tool follows a strict **domain-driven** folder structure where everything related to a feature lives together. No more hunting across `/components`, `/hooks`, and `/services` top-level folders.
62
+
63
+ The layer responsibilities are:
64
+
65
+ - **repositories** — data fetching only, no business logic
66
+ - **services** — business logic, calls repositories
67
+ - **hooks** — React state and side effects, calls services
68
+ - **containers** — wire hooks into UI, no direct data fetching
69
+ - **components** — pure presentational UI, no data dependencies
70
+ - **schemas** — Zod validation for both forms and API responses
71
+
72
+ ---
73
+
74
+ ## Requirements
75
+
76
+ - Node.js 18+
77
+ - A Next.js project with an `app/` directory (App Router)
78
+
79
+ ---
80
+
81
+ ## Local Development
82
+
83
+ ```bash
84
+ # Clone the repo
85
+ git clone https://github.com/yourname/domain-driver
86
+ cd domain-driver
87
+
88
+ # Install dependencies
89
+ npm install
90
+
91
+ # Build
92
+ npm run build
93
+
94
+ # Link globally for local testing
95
+ npm link
96
+
97
+ # Test it
98
+ domain-driver make:feature test-feature
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Roadmap
104
+
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
110
+ - [ ] Config file — customize folder structure per project
111
+
112
+ ---
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,71 @@
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.makeFeature = makeFeature;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const FEATURE_DIRS = [
40
+ 'components/server',
41
+ 'components/client',
42
+ 'containers',
43
+ 'hooks',
44
+ 'services',
45
+ 'repositories',
46
+ 'schemas',
47
+ ];
48
+ function renderTemplate(name) {
49
+ const componentName = name
50
+ .split('-')
51
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
52
+ .join('');
53
+ return `export default function ${componentName}Page() {
54
+ return (
55
+ <div>
56
+ <h1>${componentName}</h1>
57
+ </div>
58
+ );
59
+ }
60
+ `;
61
+ }
62
+ async function makeFeature(name) {
63
+ const base = path.join(process.cwd(), 'app', name);
64
+ for (const dir of FEATURE_DIRS) {
65
+ fs.mkdirSync(path.join(base, dir), { recursive: true });
66
+ fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
67
+ }
68
+ const page = renderTemplate(name);
69
+ fs.writeFileSync(path.join(base, 'page.tsx'), page);
70
+ console.log(`✅ Feature "${name}" scaffolded at ${base}`);
71
+ }
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
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>');
8
+ process.exit(1);
9
+ }
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
+ }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "domain-driver",
3
+ "version": "0.0.1",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "domain-driver": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "npx tsc",
11
+ "dev": "ts-node src/index.ts",
12
+ "test": "echo \"Error: no test specified\" && exit 1"
13
+ },
14
+ "keywords": [],
15
+ "author": "",
16
+ "license": "ISC",
17
+ "devDependencies": {
18
+ "@types/node": "^25.4.0"
19
+ },
20
+ "dependencies": {
21
+ "typescript": "^5.9.3"
22
+ }
23
+ }
@@ -0,0 +1,42 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ const FEATURE_DIRS = [
5
+ 'components/server',
6
+ 'components/client',
7
+ 'containers',
8
+ 'hooks',
9
+ 'services',
10
+ 'repositories',
11
+ 'schemas',
12
+ ];
13
+
14
+ function renderTemplate(name: string): string {
15
+ const componentName = name
16
+ .split('-')
17
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
18
+ .join('');
19
+
20
+ return `export default function ${componentName}Page() {
21
+ return (
22
+ <div>
23
+ <h1>${componentName}</h1>
24
+ </div>
25
+ );
26
+ }
27
+ `;
28
+ }
29
+
30
+ export async function makeFeature(name: string) {
31
+ const base = path.join(process.cwd(), 'app', name);
32
+
33
+ for (const dir of FEATURE_DIRS) {
34
+ fs.mkdirSync(path.join(base, dir), { recursive: true });
35
+ fs.writeFileSync(path.join(base, dir, '.gitkeep'), '');
36
+ }
37
+
38
+ const page = renderTemplate(name);
39
+ fs.writeFileSync(path.join(base, 'page.tsx'), page);
40
+
41
+ console.log(`✅ Feature "${name}" scaffolded at ${base}`);
42
+ }
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { makeFeature } from './commands/feature';
3
+
4
+ const [,, command, name] = process.argv;
5
+
6
+ if (!command || !name) {
7
+ console.error('Usage: domain-driver make:feature <name>');
8
+ process.exit(1);
9
+ }
10
+
11
+ if (command === 'make:feature') {
12
+ makeFeature(name);
13
+ } else {
14
+ console.error(`Unknown command: ${command}`);
15
+ process.exit(1);
16
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "outDir": "./dist",
6
+ "rootDir": "./src",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "types": ["node"]
10
+ },
11
+ "include": ["src/**/*"],
12
+ "exclude": ["node_modules", "dist"]
13
+ }