archforge-x 1.0.3 ā 1.0.4
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 +156 -56
- package/dist/generators/node/nestjs.js +1 -1
- package/dist/index.js +20 -15
- package/package.json +1 -1
- package/dist/cli/init.js +0 -74
package/README.md
CHANGED
|
@@ -1,90 +1,190 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ArchForge X
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A configuration-driven architecture engine for generating and enforcing production-grade project structures across multiple languages and frameworks.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Why This Exists
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Modern software development often suffers from two primary issues: **setup fatigue** and **architecture drift**. Developers spend hours configuring boilerplate for logging, caching, and database layers, only for the project's architectural boundaries to erode over time as the team grows.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **š Dependency Analysis**: Detect architectural violations and circular dependencies between layers.
|
|
11
|
-
- **š Visual Graphs**: Generate high-resolution SVG dependency graphs to visualize your architecture.
|
|
12
|
-
- **š”ļø Rule Enforcement**: Define custom architectural rules in `archforge.yaml` to ensure your team follows the intended design.
|
|
13
|
-
- **⨠Interactive CLI**: A user-friendly wizard to get you started in seconds.
|
|
9
|
+
ArchForge X solves this by moving architecture from "documentation" to "executable configuration." By defining your project's structure and rules in a central `archforge.yaml`, you ensure that every project starts with production-ready defaults and stays compliant throughout its lifecycle.
|
|
14
10
|
|
|
15
|
-
##
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Config-Driven Generation**: Generate entire project skeletons from a single YAML definition.
|
|
14
|
+
- **Architecture Enforcement**: Automatically validate naming conventions and import boundaries.
|
|
15
|
+
- **Production-Ready Defaults**: Built-in support for structured logging, health checks, and global error handling.
|
|
16
|
+
- **Multi-Stack Support**: Consistent patterns across Node.js, Python, and Go.
|
|
17
|
+
- **Zero-Drift Sync**: Re-apply architectural rules to existing projects without losing custom logic.
|
|
18
|
+
|
|
19
|
+
## Supported Capabilities
|
|
20
|
+
|
|
21
|
+
- **Architectures**: Clean Architecture (DDD), Layered Architecture, MVC.
|
|
22
|
+
- **Frameworks**: NestJS, Express, FastAPI, Django, Go Gin, Next.js.
|
|
23
|
+
- **ORMs & Databases**: Prisma, SQLAlchemy, GORM, PostgreSQL, MySQL, SQLite, MongoDB.
|
|
24
|
+
- **DevOps**: Automated Dockerfile and Docker Compose generation, GitHub Actions CI/CD workflows.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Install ArchForge X globally via npm:
|
|
16
29
|
|
|
17
30
|
```bash
|
|
18
|
-
npm install -g archforge
|
|
31
|
+
npm install -g archforge
|
|
19
32
|
```
|
|
20
33
|
|
|
21
|
-
##
|
|
34
|
+
## CLI Commands
|
|
35
|
+
|
|
36
|
+
### init
|
|
37
|
+
|
|
38
|
+
The `init` command starts an interactive wizard to bootstrap a new project.
|
|
22
39
|
|
|
23
|
-
### 1. Initialize a Project
|
|
24
|
-
Create a new architecture configuration file:
|
|
25
40
|
```bash
|
|
26
41
|
archforge init
|
|
27
42
|
```
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
44
|
+
During initialization, you will select:
|
|
45
|
+
- **Architecture Style**: Choose between Clean, Layered, or MVC.
|
|
46
|
+
- **Framework**: Select your preferred backend or frontend framework.
|
|
47
|
+
- **ORM & Database**: Configure your data persistence layer.
|
|
48
|
+
- **Optional Modules**: Add Docker support, CI/CD workflows, Caching (Redis), and more.
|
|
49
|
+
|
|
50
|
+
### sync
|
|
51
|
+
|
|
52
|
+
The `sync` command re-applies the architectural rules defined in `archforge.yaml` to your project.
|
|
53
|
+
|
|
31
54
|
```bash
|
|
32
|
-
archforge
|
|
55
|
+
archforge sync
|
|
33
56
|
```
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
- **What it changes**: Updates configuration files, architecture guardrails (e.g., ESLint rules), and missing infrastructure layers.
|
|
59
|
+
- **What it never changes**: Your business logic, use cases, or custom implementation files.
|
|
60
|
+
|
|
61
|
+
### validate
|
|
62
|
+
|
|
63
|
+
The `validate` command checks your project against the rules defined in `archforge.yaml`.
|
|
64
|
+
|
|
37
65
|
```bash
|
|
38
|
-
archforge
|
|
66
|
+
archforge validate
|
|
39
67
|
```
|
|
40
68
|
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
- **Validation**: Checks naming conventions, directory structure, and restricted import paths.
|
|
70
|
+
- **Usage**: Used locally during development or in CI pipelines to prevent architectural violations.
|
|
71
|
+
- **Behavior**: Returns a non-zero exit code on failure, making it ideal for blocking invalid PRs.
|
|
72
|
+
|
|
73
|
+
### upgrade
|
|
74
|
+
|
|
75
|
+
The `upgrade` command adds new production-grade features to an existing ArchForge project.
|
|
76
|
+
|
|
43
77
|
```bash
|
|
44
|
-
archforge
|
|
78
|
+
archforge upgrade
|
|
45
79
|
```
|
|
46
80
|
|
|
47
|
-
|
|
48
|
-
|
|
81
|
+
- **Purpose**: Safely introduces enhancements like new logging providers or health check endpoints without breaking existing code.
|
|
82
|
+
|
|
83
|
+
### generate
|
|
84
|
+
|
|
85
|
+
The `generate` command creates specific architectural components within an existing project.
|
|
86
|
+
|
|
49
87
|
```bash
|
|
50
|
-
archforge
|
|
88
|
+
archforge generate module user
|
|
51
89
|
```
|
|
52
90
|
|
|
53
|
-
|
|
91
|
+
- **Usage**: Use this to quickly add new features, layers, or modules that follow the project's established patterns.
|
|
92
|
+
- **Alias**: `create`
|
|
93
|
+
|
|
94
|
+
### graph
|
|
54
95
|
|
|
55
|
-
|
|
96
|
+
The `graph` command generates a visual representation of your project's architecture.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
archforge graph
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- **Output**: Generates an `architecture-graph.svg` file showing the relationships and dependencies between your project's layers.
|
|
103
|
+
- **Alias**: `visualize`
|
|
104
|
+
|
|
105
|
+
## Configuration (archforge.yaml)
|
|
106
|
+
|
|
107
|
+
The `archforge.yaml` file is the single source of truth for your project's architecture. It defines the structure, naming conventions, and enforcement policies.
|
|
56
108
|
|
|
57
109
|
```yaml
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
name: my-production-app
|
|
111
|
+
architecture: clean
|
|
112
|
+
framework: nestjs
|
|
113
|
+
orm: prisma
|
|
114
|
+
database: postgresql
|
|
115
|
+
|
|
116
|
+
structure:
|
|
117
|
+
layers:
|
|
118
|
+
- name: domain
|
|
119
|
+
path: src/domain
|
|
120
|
+
canImport: []
|
|
121
|
+
- name: application
|
|
122
|
+
path: src/application
|
|
123
|
+
canImport: [domain]
|
|
124
|
+
- name: infrastructure
|
|
125
|
+
path: src/infrastructure
|
|
126
|
+
canImport: [domain, application]
|
|
127
|
+
- name: presentation
|
|
128
|
+
path: src/presentation
|
|
129
|
+
canImport: [domain, application]
|
|
130
|
+
|
|
131
|
+
naming:
|
|
132
|
+
controllers: "{name}.controller.ts"
|
|
133
|
+
useCases: "{name}.use-case.ts"
|
|
134
|
+
repositories: "{name}.repository.ts"
|
|
135
|
+
|
|
136
|
+
enforcement:
|
|
137
|
+
strictImports: true
|
|
138
|
+
namingConvention: pascalCase
|
|
82
139
|
```
|
|
83
140
|
|
|
84
|
-
##
|
|
141
|
+
## Rule Enforcement & Verification
|
|
142
|
+
|
|
143
|
+
ArchForge X enforces rules through a combination of static analysis and framework-specific configurations:
|
|
144
|
+
|
|
145
|
+
1. **Local Enforcement**: During `sync`, ArchForge configures tools like ESLint with `import/no-restricted-paths` to provide real-time feedback in your IDE.
|
|
146
|
+
2. **CI Verification**: Running `archforge validate` in your CI pipeline ensures that no code violating the architecture is merged.
|
|
147
|
+
3. **Fixing Violations**: If a violation is detected (e.g., a Domain entity importing from Infrastructure), the CLI will provide a detailed report pointing to the offending file and rule.
|
|
148
|
+
|
|
149
|
+
## Running the Project
|
|
150
|
+
|
|
151
|
+
### Local Development
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Install dependencies
|
|
155
|
+
npm install
|
|
156
|
+
|
|
157
|
+
# Start in development mode with hot-reload
|
|
158
|
+
npm run start:dev
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Docker-Based Development
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# Build and start all services (App, Database, Redis)
|
|
165
|
+
docker-compose up --build
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Environment Variables
|
|
169
|
+
|
|
170
|
+
ArchForge generates a `.env.example` file. Copy it to `.env` and configure your secrets:
|
|
171
|
+
- `PORT`: Server port (default: 3000)
|
|
172
|
+
- `DATABASE_URL`: Connection string for your database.
|
|
173
|
+
- `REDIS_URL`: Connection string for Redis caching.
|
|
174
|
+
|
|
175
|
+
## Team & Company Usage
|
|
176
|
+
|
|
177
|
+
ArchForge X is designed for engineering organizations to:
|
|
178
|
+
- **Standardize**: Ensure every microservice or project follows the same structural patterns.
|
|
179
|
+
- **Onboard**: New developers can navigate any project instantly because the structure is predictable.
|
|
180
|
+
- **Scale**: Enforce best practices across hundreds of repositories without manual code reviews for "folder structure."
|
|
181
|
+
|
|
182
|
+
## Design Philosophy
|
|
85
183
|
|
|
86
|
-
|
|
184
|
+
- **Enforcement over Documentation**: Rules that aren't enforced will eventually be broken.
|
|
185
|
+
- **Production-Ready by Default**: Every project starts with the scaffolding needed for a real-world deployment.
|
|
186
|
+
- **Config-Driven Flexibility**: The tool adapts to your team's preferred patterns, not the other way around.
|
|
87
187
|
|
|
88
|
-
##
|
|
188
|
+
## Contributing & License
|
|
89
189
|
|
|
90
|
-
|
|
190
|
+
ArchForge X is open-source software licensed under the MIT License. Contributions are welcome via GitHub Pull Requests.
|
|
@@ -53,7 +53,7 @@ class NestJSGenerator extends base_1.BaseGenerator {
|
|
|
53
53
|
"pino-http": "^8.3.3",
|
|
54
54
|
"zod": "^3.22.2",
|
|
55
55
|
"ioredis": "^5.3.2",
|
|
56
|
-
"class-validator": "^0.14.
|
|
56
|
+
"class-validator": "^0.14.3",
|
|
57
57
|
"class-transformer": "^0.5.1",
|
|
58
58
|
...(options.orm === "prisma" ? { "@prisma/client": "^5.0.0" } : {})
|
|
59
59
|
},
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const commander_1 = require("commander");
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const init_1 = require("./cli/init");
|
|
10
9
|
const interactive_1 = require("./cli/interactive");
|
|
11
10
|
const sync_1 = require("./cli/commands/sync");
|
|
12
11
|
const parser_1 = require("./core/architecture/parser");
|
|
@@ -27,16 +26,22 @@ const loadConfig = (configPath) => {
|
|
|
27
26
|
return (0, parser_1.loadArchitecture)(configPath);
|
|
28
27
|
};
|
|
29
28
|
// --- COMMANDS ---
|
|
30
|
-
program
|
|
29
|
+
program
|
|
30
|
+
.command("init")
|
|
31
|
+
.description("Initialize a new project with interactive wizard (Recommended)")
|
|
32
|
+
.action(async () => {
|
|
33
|
+
await (0, interactive_1.interactiveCLI)();
|
|
34
|
+
});
|
|
31
35
|
program
|
|
32
36
|
.command("sync")
|
|
33
|
-
.description("
|
|
37
|
+
.description("Synchronize architecture with archforge.yaml and validate structure")
|
|
34
38
|
.action(async () => {
|
|
35
39
|
await (0, sync_1.syncCommand)();
|
|
36
40
|
});
|
|
37
41
|
program
|
|
38
42
|
.command("generate")
|
|
39
|
-
.
|
|
43
|
+
.alias("create")
|
|
44
|
+
.description("Scaffold a project or module based on architecture definition")
|
|
40
45
|
.option("-c, --config <path>", "Path to yaml config", "archforge.yaml")
|
|
41
46
|
.option("-m, --mode <mode>", "Generation mode: 'standard' or 'professional'", "professional")
|
|
42
47
|
.action(async (options) => {
|
|
@@ -60,14 +65,15 @@ program
|
|
|
60
65
|
}
|
|
61
66
|
});
|
|
62
67
|
program
|
|
63
|
-
.command("
|
|
64
|
-
.
|
|
68
|
+
.command("validate")
|
|
69
|
+
.alias("check")
|
|
70
|
+
.description("Validate project structure and dependencies against rules")
|
|
65
71
|
.option("-c, --config <path>", "Path to yaml config", "archforge.yaml")
|
|
66
72
|
.option("--ignore-tests", "Exclude test files from analysis")
|
|
67
73
|
.option("-o, --output <file>", "Export report to JSON/Markdown")
|
|
68
74
|
.action((options) => {
|
|
69
75
|
try {
|
|
70
|
-
console.log(chalk_1.default.cyan("š
|
|
76
|
+
console.log(chalk_1.default.cyan("š Validating Architecture..."));
|
|
71
77
|
const arch = loadConfig(options.config);
|
|
72
78
|
const violations = (0, dependency_1.analyzeDependencies)(arch, {
|
|
73
79
|
ignoreTests: options.ignoreTests,
|
|
@@ -78,13 +84,13 @@ program
|
|
|
78
84
|
process.exit(1);
|
|
79
85
|
}
|
|
80
86
|
catch (err) {
|
|
81
|
-
console.error(chalk_1.default.red.bold("\nā
|
|
87
|
+
console.error(chalk_1.default.red.bold("\nā Validation Error:"), err.message);
|
|
82
88
|
process.exit(1);
|
|
83
89
|
}
|
|
84
90
|
});
|
|
85
91
|
program
|
|
86
92
|
.command("audit")
|
|
87
|
-
.description("
|
|
93
|
+
.description("Perform a deep architectural audit with auto-fix suggestions")
|
|
88
94
|
.option("-c, --config <path>", "Path to yaml config", "archforge.yaml")
|
|
89
95
|
.option("-o, --output <file>", "Export audit results")
|
|
90
96
|
.action((options) => {
|
|
@@ -100,8 +106,9 @@ program
|
|
|
100
106
|
}
|
|
101
107
|
});
|
|
102
108
|
program
|
|
103
|
-
.command("
|
|
104
|
-
.
|
|
109
|
+
.command("graph")
|
|
110
|
+
.alias("visualize")
|
|
111
|
+
.description("Generate a visual dependency graph (SVG)")
|
|
105
112
|
.option("-c, --config <path>", "Path to yaml config", "archforge.yaml")
|
|
106
113
|
.option("-o, --output <file>", "Output file path", "architecture-graph.svg")
|
|
107
114
|
.action(async (options) => {
|
|
@@ -115,10 +122,8 @@ program
|
|
|
115
122
|
console.error(chalk_1.default.red.bold("\nā Visualization Error:"), err.message);
|
|
116
123
|
}
|
|
117
124
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
.description("Interactive Wizard (Recommended)")
|
|
121
|
-
.action(async () => {
|
|
125
|
+
// Set default command to init
|
|
126
|
+
program.action(async () => {
|
|
122
127
|
await (0, interactive_1.interactiveCLI)();
|
|
123
128
|
});
|
|
124
129
|
program.parse(process.argv);
|
package/package.json
CHANGED
package/dist/cli/init.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initCommand = void 0;
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
exports.initCommand = new commander_1.Command("init")
|
|
12
|
-
.description("Initialize a new architecture configuration file (archforge.yaml)")
|
|
13
|
-
.action(() => {
|
|
14
|
-
const configPath = path_1.default.resolve(process.cwd(), "archforge.yaml");
|
|
15
|
-
// 1. Safety Check: Don't overwrite existing config
|
|
16
|
-
if (fs_1.default.existsSync(configPath)) {
|
|
17
|
-
console.log(chalk_1.default.yellow("ā ļø Configuration file 'archforge.yaml' already exists."));
|
|
18
|
-
console.log(chalk_1.default.gray(` Path: ${configPath}`));
|
|
19
|
-
console.log(chalk_1.default.blue(" Run 'archforge analyze' or 'archforge generate' to use it."));
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const template = `
|
|
23
|
-
version: "1.0"
|
|
24
|
-
name: "Enterprise Architecture Config"
|
|
25
|
-
project:
|
|
26
|
-
name: "my-awesome-project"
|
|
27
|
-
root: "."
|
|
28
|
-
|
|
29
|
-
metadata:
|
|
30
|
-
type: "clean" # Options: clean, ddd, hexagonal, layered
|
|
31
|
-
language: "ts" # Options: ts, js, py, go
|
|
32
|
-
framework: "nestjs" # Options: nestjs, express, django, flask, gin
|
|
33
|
-
version: "1.0.0"
|
|
34
|
-
modules: # Optional modules to scaffold
|
|
35
|
-
- "auth"
|
|
36
|
-
- "docker"
|
|
37
|
-
|
|
38
|
-
# Define your architecture layers and dependency rules here
|
|
39
|
-
layers:
|
|
40
|
-
- name: "domain"
|
|
41
|
-
path: "src/domain"
|
|
42
|
-
description: "Core business logic and entities (Enterprise Rules)"
|
|
43
|
-
strict: true
|
|
44
|
-
forbiddenImports: ["infrastructure", "interface", "application"]
|
|
45
|
-
|
|
46
|
-
- name: "application"
|
|
47
|
-
path: "src/application"
|
|
48
|
-
description: "Use cases and application logic"
|
|
49
|
-
allowedImports: ["domain"]
|
|
50
|
-
|
|
51
|
-
- name: "infrastructure"
|
|
52
|
-
path: "src/infrastructure"
|
|
53
|
-
description: "External tools, databases, and third-party services"
|
|
54
|
-
allowedImports: ["domain", "application"]
|
|
55
|
-
|
|
56
|
-
- name: "interface"
|
|
57
|
-
path: "src/interface"
|
|
58
|
-
description: "Controllers, API endpoints, and Presenters"
|
|
59
|
-
allowedImports: ["application"]
|
|
60
|
-
`.trim();
|
|
61
|
-
// 3. Write the file
|
|
62
|
-
try {
|
|
63
|
-
fs_1.default.writeFileSync(configPath, template, "utf-8");
|
|
64
|
-
console.log(chalk_1.default.green.bold("ā
Successfully initialized 'archforge.yaml'"));
|
|
65
|
-
console.log(chalk_1.default.white(" You can now customize the layers in the file."));
|
|
66
|
-
console.log(chalk_1.default.gray("\nNext steps:"));
|
|
67
|
-
console.log(chalk_1.default.cyan(" 1. archforge generate"));
|
|
68
|
-
console.log(chalk_1.default.cyan(" 2. archforge analyze"));
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
console.error(chalk_1.default.red("ā Failed to create configuration file:"), err.message);
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
});
|