@gravito/scaffold 3.0.1 → 3.1.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/dist/index.cjs +184 -0
- package/dist/index.d.cts +89 -1
- package/dist/index.d.ts +89 -1
- package/dist/index.js +183 -0
- package/package.json +7 -5
- package/templates/features/otel/package.json +6 -6
- package/templates/features/redis/package.json +4 -4
- package/templates/overlays/core/package.json +4 -4
- package/templates/overlays/enterprise/package.json +6 -6
- package/templates/overlays/scale/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
BaseGenerator: () => BaseGenerator,
|
|
34
34
|
CleanArchitectureGenerator: () => CleanArchitectureGenerator,
|
|
35
35
|
DddGenerator: () => DddGenerator,
|
|
36
|
+
DependencyValidator: () => DependencyValidator,
|
|
36
37
|
EnterpriseMvcGenerator: () => EnterpriseMvcGenerator,
|
|
37
38
|
EnvironmentDetector: () => EnvironmentDetector,
|
|
38
39
|
FileMerger: () => FileMerger,
|
|
@@ -44,6 +45,147 @@ __export(index_exports, {
|
|
|
44
45
|
});
|
|
45
46
|
module.exports = __toCommonJS(index_exports);
|
|
46
47
|
|
|
48
|
+
// src/DependencyValidator.ts
|
|
49
|
+
var DependencyValidator = class _DependencyValidator {
|
|
50
|
+
/**
|
|
51
|
+
* Driver 到 Package 的映射規則
|
|
52
|
+
*/
|
|
53
|
+
static DRIVER_DEPENDENCIES = [
|
|
54
|
+
{
|
|
55
|
+
driver: "redis",
|
|
56
|
+
requiredPackages: ["@gravito/ion"],
|
|
57
|
+
description: "Redis cache/queue driver requires @gravito/ion"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
driver: "postgresql",
|
|
61
|
+
requiredPackages: ["@gravito/atlas", "pg"],
|
|
62
|
+
description: "PostgreSQL driver requires @gravito/atlas and pg"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
driver: "mysql",
|
|
66
|
+
requiredPackages: ["@gravito/atlas", "mysql2"],
|
|
67
|
+
description: "MySQL driver requires @gravito/atlas and mysql2"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
driver: "sqlite",
|
|
71
|
+
requiredPackages: ["@gravito/atlas", "better-sqlite3"],
|
|
72
|
+
description: "SQLite driver requires @gravito/atlas and better-sqlite3"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
driver: "s3",
|
|
76
|
+
requiredPackages: ["@gravito/stasis", "@aws-sdk/client-s3"],
|
|
77
|
+
description: "S3 storage driver requires @gravito/stasis and AWS SDK"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
driver: "r2",
|
|
81
|
+
requiredPackages: ["@gravito/stasis", "@aws-sdk/client-s3"],
|
|
82
|
+
description: "R2 storage driver requires @gravito/stasis and AWS SDK"
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* Feature 衝突規則
|
|
87
|
+
*/
|
|
88
|
+
static CONFLICTS = [
|
|
89
|
+
{
|
|
90
|
+
features: ["postgres", "mysql", "sqlite"],
|
|
91
|
+
reason: "\u4E0D\u80FD\u540C\u6642\u4F7F\u7528\u591A\u500B\u8CC7\u6599\u5EAB driver (PostgreSQL, MySQL, SQLite)"
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* Feature 依賴映射
|
|
96
|
+
*/
|
|
97
|
+
static FEATURE_DEPENDENCIES = {
|
|
98
|
+
stream: ["@gravito/beam"],
|
|
99
|
+
monitor: ["@gravito/spectrum"],
|
|
100
|
+
graphql: ["@gravito/constellation"]
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* 驗證 Profile 配置
|
|
104
|
+
*
|
|
105
|
+
* @param config - Profile 配置
|
|
106
|
+
* @param packageJson - 專案的 package.json 內容
|
|
107
|
+
* @returns 驗證結果
|
|
108
|
+
*/
|
|
109
|
+
validate(config, packageJson) {
|
|
110
|
+
const errors = [];
|
|
111
|
+
const warnings = [];
|
|
112
|
+
this.validateDriverDependencies(config, packageJson, errors);
|
|
113
|
+
this.validateFeatureConflicts(config, errors);
|
|
114
|
+
this.validateFeatureDependencies(config, packageJson, warnings);
|
|
115
|
+
return {
|
|
116
|
+
valid: errors.length === 0,
|
|
117
|
+
errors,
|
|
118
|
+
warnings
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 驗證 driver 依賴
|
|
123
|
+
*/
|
|
124
|
+
validateDriverDependencies(config, packageJson, errors) {
|
|
125
|
+
for (const [service, driver] of Object.entries(config.drivers)) {
|
|
126
|
+
const rule = _DependencyValidator.DRIVER_DEPENDENCIES.find((r) => r.driver === driver);
|
|
127
|
+
if (rule) {
|
|
128
|
+
for (const pkg of rule.requiredPackages) {
|
|
129
|
+
if (!this.hasPackage(packageJson, pkg)) {
|
|
130
|
+
errors.push(`\u7F3A\u5C11\u4F9D\u8CF4: ${pkg} (${service} driver '${driver}' \u6240\u9700)`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 驗證 feature 衝突
|
|
138
|
+
*/
|
|
139
|
+
validateFeatureConflicts(config, errors) {
|
|
140
|
+
for (const conflict of _DependencyValidator.CONFLICTS) {
|
|
141
|
+
const conflictingFeatures = conflict.features.filter((f) => config.features.includes(f));
|
|
142
|
+
if (conflictingFeatures.length > 1) {
|
|
143
|
+
errors.push(`Feature \u885D\u7A81: ${conflictingFeatures.join(", ")} - ${conflict.reason}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 驗證 feature 依賴
|
|
149
|
+
*/
|
|
150
|
+
validateFeatureDependencies(config, packageJson, warnings) {
|
|
151
|
+
for (const feature of config.features) {
|
|
152
|
+
const requiredPackages = _DependencyValidator.FEATURE_DEPENDENCIES[feature];
|
|
153
|
+
if (requiredPackages) {
|
|
154
|
+
for (const pkg of requiredPackages) {
|
|
155
|
+
if (!this.hasPackage(packageJson, pkg)) {
|
|
156
|
+
warnings.push(`Feature "${feature}" \u9700\u8981 ${pkg}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 檢查 package.json 是否包含指定 package
|
|
164
|
+
*/
|
|
165
|
+
hasPackage(packageJson, packageName) {
|
|
166
|
+
return packageJson.dependencies?.[packageName] !== void 0 || packageJson.devDependencies?.[packageName] !== void 0;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 建議安裝缺失的依賴
|
|
170
|
+
*
|
|
171
|
+
* @param result - 驗證結果
|
|
172
|
+
* @returns 安裝命令建議
|
|
173
|
+
*/
|
|
174
|
+
static suggestInstallCommand(result) {
|
|
175
|
+
if (result.errors.length === 0) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
const missingPackages = result.errors.map((err) => {
|
|
179
|
+
const match = err.match(/缺少依賴: ([@\w/-]+)/);
|
|
180
|
+
return match ? match[1] : null;
|
|
181
|
+
}).filter((pkg) => pkg !== null);
|
|
182
|
+
if (missingPackages.length === 0) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
return `bun add ${missingPackages.join(" ")}`;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
47
189
|
// src/EnvironmentDetector.ts
|
|
48
190
|
var EnvironmentDetector = class {
|
|
49
191
|
detect() {
|
|
@@ -4374,6 +4516,11 @@ export class User extends Model {
|
|
|
4374
4516
|
// ─────────────────────────────────────────────────────────────
|
|
4375
4517
|
// Action Generators
|
|
4376
4518
|
// ─────────────────────────────────────────────────────────────
|
|
4519
|
+
/**
|
|
4520
|
+
* Generates the base Action class source code.
|
|
4521
|
+
*
|
|
4522
|
+
* @returns The complete source code for the abstract Action class.
|
|
4523
|
+
*/
|
|
4377
4524
|
generateActionBase() {
|
|
4378
4525
|
return `/**
|
|
4379
4526
|
* Action Base Class
|
|
@@ -4390,6 +4537,11 @@ export abstract class Action<TInput = unknown, TOutput = unknown> {
|
|
|
4390
4537
|
}
|
|
4391
4538
|
`;
|
|
4392
4539
|
}
|
|
4540
|
+
/**
|
|
4541
|
+
* Generates the GetServerStatusAction source code.
|
|
4542
|
+
*
|
|
4543
|
+
* @returns The complete source code for the example action.
|
|
4544
|
+
*/
|
|
4393
4545
|
generateGetServerStatusAction() {
|
|
4394
4546
|
return `/**
|
|
4395
4547
|
* Get Server Status Action
|
|
@@ -4412,6 +4564,11 @@ export class GetServerStatusAction extends Action<void, ServerStatusResponse> {
|
|
|
4412
4564
|
// ─────────────────────────────────────────────────────────────
|
|
4413
4565
|
// Controller Generators
|
|
4414
4566
|
// ─────────────────────────────────────────────────────────────
|
|
4567
|
+
/**
|
|
4568
|
+
* Generates the Server Controller source code.
|
|
4569
|
+
*
|
|
4570
|
+
* @returns The complete source code for the ServerController class.
|
|
4571
|
+
*/
|
|
4415
4572
|
generateServerController() {
|
|
4416
4573
|
return `/**
|
|
4417
4574
|
* Server Controller
|
|
@@ -4439,6 +4596,11 @@ export class ServerController {
|
|
|
4439
4596
|
// ─────────────────────────────────────────────────────────────
|
|
4440
4597
|
// Type Generators
|
|
4441
4598
|
// ─────────────────────────────────────────────────────────────
|
|
4599
|
+
/**
|
|
4600
|
+
* Generates the ServerStatusResponse type definition.
|
|
4601
|
+
*
|
|
4602
|
+
* @returns The complete source code for the response interface.
|
|
4603
|
+
*/
|
|
4442
4604
|
generateServerStatusResponse() {
|
|
4443
4605
|
return `/**
|
|
4444
4606
|
* Server Status Response Type
|
|
@@ -4454,6 +4616,11 @@ export interface ServerStatusResponse {
|
|
|
4454
4616
|
// ─────────────────────────────────────────────────────────────
|
|
4455
4617
|
// Routes & Bootstrap
|
|
4456
4618
|
// ─────────────────────────────────────────────────────────────
|
|
4619
|
+
/**
|
|
4620
|
+
* Generates the API routes registration function.
|
|
4621
|
+
*
|
|
4622
|
+
* @returns The complete source code for the api.ts routes file.
|
|
4623
|
+
*/
|
|
4457
4624
|
generateApiRoutes() {
|
|
4458
4625
|
return `/**
|
|
4459
4626
|
* API Routes Registration
|
|
@@ -4472,6 +4639,12 @@ export function registerApiRoutes(router: Router) {
|
|
|
4472
4639
|
}
|
|
4473
4640
|
`;
|
|
4474
4641
|
}
|
|
4642
|
+
/**
|
|
4643
|
+
* Generates the App Service Provider source code.
|
|
4644
|
+
*
|
|
4645
|
+
* @param context - The generator context containing project details.
|
|
4646
|
+
* @returns The complete source code for AppServiceProvider.
|
|
4647
|
+
*/
|
|
4475
4648
|
generateAppServiceProvider(context) {
|
|
4476
4649
|
return `/**
|
|
4477
4650
|
* App Service Provider
|
|
@@ -4500,6 +4673,11 @@ export { MiddlewareProvider } from './MiddlewareProvider'
|
|
|
4500
4673
|
export { RouteProvider } from './RouteProvider'
|
|
4501
4674
|
`;
|
|
4502
4675
|
}
|
|
4676
|
+
/**
|
|
4677
|
+
* Generates the Middleware Service Provider source code.
|
|
4678
|
+
*
|
|
4679
|
+
* @returns The complete source code for MiddlewareProvider.
|
|
4680
|
+
*/
|
|
4503
4681
|
generateMiddlewareProvider() {
|
|
4504
4682
|
return `/**
|
|
4505
4683
|
* Middleware Service Provider
|
|
@@ -4524,6 +4702,11 @@ export class MiddlewareProvider extends ServiceProvider {
|
|
|
4524
4702
|
}
|
|
4525
4703
|
`;
|
|
4526
4704
|
}
|
|
4705
|
+
/**
|
|
4706
|
+
* Generates the Route Service Provider source code.
|
|
4707
|
+
*
|
|
4708
|
+
* @returns The complete source code for RouteProvider.
|
|
4709
|
+
*/
|
|
4527
4710
|
generateRouteProvider() {
|
|
4528
4711
|
return `/**
|
|
4529
4712
|
* Route Service Provider
|
|
@@ -4912,6 +5095,7 @@ var Scaffold = class {
|
|
|
4912
5095
|
BaseGenerator,
|
|
4913
5096
|
CleanArchitectureGenerator,
|
|
4914
5097
|
DddGenerator,
|
|
5098
|
+
DependencyValidator,
|
|
4915
5099
|
EnterpriseMvcGenerator,
|
|
4916
5100
|
EnvironmentDetector,
|
|
4917
5101
|
FileMerger,
|
package/dist/index.d.cts
CHANGED
|
@@ -49,6 +49,94 @@ declare class ProfileResolver {
|
|
|
49
49
|
isValidFeature(feature: string): boolean;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* package.json 結構
|
|
54
|
+
*/
|
|
55
|
+
interface PackageJson {
|
|
56
|
+
name?: string;
|
|
57
|
+
version?: string;
|
|
58
|
+
dependencies?: Record<string, string>;
|
|
59
|
+
devDependencies?: Record<string, string>;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 驗證結果
|
|
64
|
+
*/
|
|
65
|
+
interface ValidationResult {
|
|
66
|
+
/** 是否通過驗證 */
|
|
67
|
+
valid: boolean;
|
|
68
|
+
/** 錯誤訊息列表 (阻塞性問題) */
|
|
69
|
+
errors: string[];
|
|
70
|
+
/** 警告訊息列表 (非阻塞性問題) */
|
|
71
|
+
warnings: string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 依賴驗證器
|
|
75
|
+
*
|
|
76
|
+
* 負責驗證 Profile 配置的依賴完整性,包括:
|
|
77
|
+
* - Driver 必需的 packages
|
|
78
|
+
* - Feature 之間的衝突
|
|
79
|
+
* - Feature 的依賴關係
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const validator = new DependencyValidator()
|
|
84
|
+
* const result = validator.validate(profileConfig, packageJson)
|
|
85
|
+
*
|
|
86
|
+
* if (!result.valid) {
|
|
87
|
+
* console.error('依賴驗證失敗:', result.errors)
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @since 3.1.0
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
declare class DependencyValidator {
|
|
95
|
+
/**
|
|
96
|
+
* Driver 到 Package 的映射規則
|
|
97
|
+
*/
|
|
98
|
+
private static readonly DRIVER_DEPENDENCIES;
|
|
99
|
+
/**
|
|
100
|
+
* Feature 衝突規則
|
|
101
|
+
*/
|
|
102
|
+
private static readonly CONFLICTS;
|
|
103
|
+
/**
|
|
104
|
+
* Feature 依賴映射
|
|
105
|
+
*/
|
|
106
|
+
private static readonly FEATURE_DEPENDENCIES;
|
|
107
|
+
/**
|
|
108
|
+
* 驗證 Profile 配置
|
|
109
|
+
*
|
|
110
|
+
* @param config - Profile 配置
|
|
111
|
+
* @param packageJson - 專案的 package.json 內容
|
|
112
|
+
* @returns 驗證結果
|
|
113
|
+
*/
|
|
114
|
+
validate(config: ProfileConfig, packageJson: PackageJson): ValidationResult;
|
|
115
|
+
/**
|
|
116
|
+
* 驗證 driver 依賴
|
|
117
|
+
*/
|
|
118
|
+
private validateDriverDependencies;
|
|
119
|
+
/**
|
|
120
|
+
* 驗證 feature 衝突
|
|
121
|
+
*/
|
|
122
|
+
private validateFeatureConflicts;
|
|
123
|
+
/**
|
|
124
|
+
* 驗證 feature 依賴
|
|
125
|
+
*/
|
|
126
|
+
private validateFeatureDependencies;
|
|
127
|
+
/**
|
|
128
|
+
* 檢查 package.json 是否包含指定 package
|
|
129
|
+
*/
|
|
130
|
+
private hasPackage;
|
|
131
|
+
/**
|
|
132
|
+
* 建議安裝缺失的依賴
|
|
133
|
+
*
|
|
134
|
+
* @param result - 驗證結果
|
|
135
|
+
* @returns 安裝命令建議
|
|
136
|
+
*/
|
|
137
|
+
static suggestInstallCommand(result: ValidationResult): string | null;
|
|
138
|
+
}
|
|
139
|
+
|
|
52
140
|
/**
|
|
53
141
|
* Represents the results of an environment detection scan.
|
|
54
142
|
*
|
|
@@ -595,4 +683,4 @@ declare class Scaffold {
|
|
|
595
683
|
generateProvider(_targetDir: string, _providerName: string): Promise<ScaffoldResult>;
|
|
596
684
|
}
|
|
597
685
|
|
|
598
|
-
export { type ArchitectureType, BaseGenerator, CleanArchitectureGenerator, DddGenerator, type DetectedEnvironment, EnterpriseMvcGenerator, EnvironmentDetector, FileMerger, type GeneratorConfig, type GeneratorContext, type LockFile, LockGenerator, type ProfileConfig, ProfileResolver, type ProfileType, SatelliteGenerator, Scaffold, type ScaffoldOptions, type StubConfig, StubGenerator, type StubVariables };
|
|
686
|
+
export { type ArchitectureType, BaseGenerator, CleanArchitectureGenerator, DddGenerator, DependencyValidator, type DetectedEnvironment, EnterpriseMvcGenerator, EnvironmentDetector, FileMerger, type GeneratorConfig, type GeneratorContext, type LockFile, LockGenerator, type PackageJson, type ProfileConfig, ProfileResolver, type ProfileType, SatelliteGenerator, Scaffold, type ScaffoldOptions, type StubConfig, StubGenerator, type StubVariables, type ValidationResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,94 @@ declare class ProfileResolver {
|
|
|
49
49
|
isValidFeature(feature: string): boolean;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* package.json 結構
|
|
54
|
+
*/
|
|
55
|
+
interface PackageJson {
|
|
56
|
+
name?: string;
|
|
57
|
+
version?: string;
|
|
58
|
+
dependencies?: Record<string, string>;
|
|
59
|
+
devDependencies?: Record<string, string>;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 驗證結果
|
|
64
|
+
*/
|
|
65
|
+
interface ValidationResult {
|
|
66
|
+
/** 是否通過驗證 */
|
|
67
|
+
valid: boolean;
|
|
68
|
+
/** 錯誤訊息列表 (阻塞性問題) */
|
|
69
|
+
errors: string[];
|
|
70
|
+
/** 警告訊息列表 (非阻塞性問題) */
|
|
71
|
+
warnings: string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 依賴驗證器
|
|
75
|
+
*
|
|
76
|
+
* 負責驗證 Profile 配置的依賴完整性,包括:
|
|
77
|
+
* - Driver 必需的 packages
|
|
78
|
+
* - Feature 之間的衝突
|
|
79
|
+
* - Feature 的依賴關係
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const validator = new DependencyValidator()
|
|
84
|
+
* const result = validator.validate(profileConfig, packageJson)
|
|
85
|
+
*
|
|
86
|
+
* if (!result.valid) {
|
|
87
|
+
* console.error('依賴驗證失敗:', result.errors)
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @since 3.1.0
|
|
92
|
+
* @public
|
|
93
|
+
*/
|
|
94
|
+
declare class DependencyValidator {
|
|
95
|
+
/**
|
|
96
|
+
* Driver 到 Package 的映射規則
|
|
97
|
+
*/
|
|
98
|
+
private static readonly DRIVER_DEPENDENCIES;
|
|
99
|
+
/**
|
|
100
|
+
* Feature 衝突規則
|
|
101
|
+
*/
|
|
102
|
+
private static readonly CONFLICTS;
|
|
103
|
+
/**
|
|
104
|
+
* Feature 依賴映射
|
|
105
|
+
*/
|
|
106
|
+
private static readonly FEATURE_DEPENDENCIES;
|
|
107
|
+
/**
|
|
108
|
+
* 驗證 Profile 配置
|
|
109
|
+
*
|
|
110
|
+
* @param config - Profile 配置
|
|
111
|
+
* @param packageJson - 專案的 package.json 內容
|
|
112
|
+
* @returns 驗證結果
|
|
113
|
+
*/
|
|
114
|
+
validate(config: ProfileConfig, packageJson: PackageJson): ValidationResult;
|
|
115
|
+
/**
|
|
116
|
+
* 驗證 driver 依賴
|
|
117
|
+
*/
|
|
118
|
+
private validateDriverDependencies;
|
|
119
|
+
/**
|
|
120
|
+
* 驗證 feature 衝突
|
|
121
|
+
*/
|
|
122
|
+
private validateFeatureConflicts;
|
|
123
|
+
/**
|
|
124
|
+
* 驗證 feature 依賴
|
|
125
|
+
*/
|
|
126
|
+
private validateFeatureDependencies;
|
|
127
|
+
/**
|
|
128
|
+
* 檢查 package.json 是否包含指定 package
|
|
129
|
+
*/
|
|
130
|
+
private hasPackage;
|
|
131
|
+
/**
|
|
132
|
+
* 建議安裝缺失的依賴
|
|
133
|
+
*
|
|
134
|
+
* @param result - 驗證結果
|
|
135
|
+
* @returns 安裝命令建議
|
|
136
|
+
*/
|
|
137
|
+
static suggestInstallCommand(result: ValidationResult): string | null;
|
|
138
|
+
}
|
|
139
|
+
|
|
52
140
|
/**
|
|
53
141
|
* Represents the results of an environment detection scan.
|
|
54
142
|
*
|
|
@@ -595,4 +683,4 @@ declare class Scaffold {
|
|
|
595
683
|
generateProvider(_targetDir: string, _providerName: string): Promise<ScaffoldResult>;
|
|
596
684
|
}
|
|
597
685
|
|
|
598
|
-
export { type ArchitectureType, BaseGenerator, CleanArchitectureGenerator, DddGenerator, type DetectedEnvironment, EnterpriseMvcGenerator, EnvironmentDetector, FileMerger, type GeneratorConfig, type GeneratorContext, type LockFile, LockGenerator, type ProfileConfig, ProfileResolver, type ProfileType, SatelliteGenerator, Scaffold, type ScaffoldOptions, type StubConfig, StubGenerator, type StubVariables };
|
|
686
|
+
export { type ArchitectureType, BaseGenerator, CleanArchitectureGenerator, DddGenerator, DependencyValidator, type DetectedEnvironment, EnterpriseMvcGenerator, EnvironmentDetector, FileMerger, type GeneratorConfig, type GeneratorContext, type LockFile, LockGenerator, type PackageJson, type ProfileConfig, ProfileResolver, type ProfileType, SatelliteGenerator, Scaffold, type ScaffoldOptions, type StubConfig, StubGenerator, type StubVariables, type ValidationResult };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,144 @@
|
|
|
1
|
+
// src/DependencyValidator.ts
|
|
2
|
+
var DependencyValidator = class _DependencyValidator {
|
|
3
|
+
/**
|
|
4
|
+
* Driver 到 Package 的映射規則
|
|
5
|
+
*/
|
|
6
|
+
static DRIVER_DEPENDENCIES = [
|
|
7
|
+
{
|
|
8
|
+
driver: "redis",
|
|
9
|
+
requiredPackages: ["@gravito/ion"],
|
|
10
|
+
description: "Redis cache/queue driver requires @gravito/ion"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
driver: "postgresql",
|
|
14
|
+
requiredPackages: ["@gravito/atlas", "pg"],
|
|
15
|
+
description: "PostgreSQL driver requires @gravito/atlas and pg"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
driver: "mysql",
|
|
19
|
+
requiredPackages: ["@gravito/atlas", "mysql2"],
|
|
20
|
+
description: "MySQL driver requires @gravito/atlas and mysql2"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
driver: "sqlite",
|
|
24
|
+
requiredPackages: ["@gravito/atlas", "better-sqlite3"],
|
|
25
|
+
description: "SQLite driver requires @gravito/atlas and better-sqlite3"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
driver: "s3",
|
|
29
|
+
requiredPackages: ["@gravito/stasis", "@aws-sdk/client-s3"],
|
|
30
|
+
description: "S3 storage driver requires @gravito/stasis and AWS SDK"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
driver: "r2",
|
|
34
|
+
requiredPackages: ["@gravito/stasis", "@aws-sdk/client-s3"],
|
|
35
|
+
description: "R2 storage driver requires @gravito/stasis and AWS SDK"
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Feature 衝突規則
|
|
40
|
+
*/
|
|
41
|
+
static CONFLICTS = [
|
|
42
|
+
{
|
|
43
|
+
features: ["postgres", "mysql", "sqlite"],
|
|
44
|
+
reason: "\u4E0D\u80FD\u540C\u6642\u4F7F\u7528\u591A\u500B\u8CC7\u6599\u5EAB driver (PostgreSQL, MySQL, SQLite)"
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Feature 依賴映射
|
|
49
|
+
*/
|
|
50
|
+
static FEATURE_DEPENDENCIES = {
|
|
51
|
+
stream: ["@gravito/beam"],
|
|
52
|
+
monitor: ["@gravito/spectrum"],
|
|
53
|
+
graphql: ["@gravito/constellation"]
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* 驗證 Profile 配置
|
|
57
|
+
*
|
|
58
|
+
* @param config - Profile 配置
|
|
59
|
+
* @param packageJson - 專案的 package.json 內容
|
|
60
|
+
* @returns 驗證結果
|
|
61
|
+
*/
|
|
62
|
+
validate(config, packageJson) {
|
|
63
|
+
const errors = [];
|
|
64
|
+
const warnings = [];
|
|
65
|
+
this.validateDriverDependencies(config, packageJson, errors);
|
|
66
|
+
this.validateFeatureConflicts(config, errors);
|
|
67
|
+
this.validateFeatureDependencies(config, packageJson, warnings);
|
|
68
|
+
return {
|
|
69
|
+
valid: errors.length === 0,
|
|
70
|
+
errors,
|
|
71
|
+
warnings
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 驗證 driver 依賴
|
|
76
|
+
*/
|
|
77
|
+
validateDriverDependencies(config, packageJson, errors) {
|
|
78
|
+
for (const [service, driver] of Object.entries(config.drivers)) {
|
|
79
|
+
const rule = _DependencyValidator.DRIVER_DEPENDENCIES.find((r) => r.driver === driver);
|
|
80
|
+
if (rule) {
|
|
81
|
+
for (const pkg of rule.requiredPackages) {
|
|
82
|
+
if (!this.hasPackage(packageJson, pkg)) {
|
|
83
|
+
errors.push(`\u7F3A\u5C11\u4F9D\u8CF4: ${pkg} (${service} driver '${driver}' \u6240\u9700)`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 驗證 feature 衝突
|
|
91
|
+
*/
|
|
92
|
+
validateFeatureConflicts(config, errors) {
|
|
93
|
+
for (const conflict of _DependencyValidator.CONFLICTS) {
|
|
94
|
+
const conflictingFeatures = conflict.features.filter((f) => config.features.includes(f));
|
|
95
|
+
if (conflictingFeatures.length > 1) {
|
|
96
|
+
errors.push(`Feature \u885D\u7A81: ${conflictingFeatures.join(", ")} - ${conflict.reason}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 驗證 feature 依賴
|
|
102
|
+
*/
|
|
103
|
+
validateFeatureDependencies(config, packageJson, warnings) {
|
|
104
|
+
for (const feature of config.features) {
|
|
105
|
+
const requiredPackages = _DependencyValidator.FEATURE_DEPENDENCIES[feature];
|
|
106
|
+
if (requiredPackages) {
|
|
107
|
+
for (const pkg of requiredPackages) {
|
|
108
|
+
if (!this.hasPackage(packageJson, pkg)) {
|
|
109
|
+
warnings.push(`Feature "${feature}" \u9700\u8981 ${pkg}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* 檢查 package.json 是否包含指定 package
|
|
117
|
+
*/
|
|
118
|
+
hasPackage(packageJson, packageName) {
|
|
119
|
+
return packageJson.dependencies?.[packageName] !== void 0 || packageJson.devDependencies?.[packageName] !== void 0;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 建議安裝缺失的依賴
|
|
123
|
+
*
|
|
124
|
+
* @param result - 驗證結果
|
|
125
|
+
* @returns 安裝命令建議
|
|
126
|
+
*/
|
|
127
|
+
static suggestInstallCommand(result) {
|
|
128
|
+
if (result.errors.length === 0) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const missingPackages = result.errors.map((err) => {
|
|
132
|
+
const match = err.match(/缺少依賴: ([@\w/-]+)/);
|
|
133
|
+
return match ? match[1] : null;
|
|
134
|
+
}).filter((pkg) => pkg !== null);
|
|
135
|
+
if (missingPackages.length === 0) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return `bun add ${missingPackages.join(" ")}`;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
1
142
|
// src/EnvironmentDetector.ts
|
|
2
143
|
var EnvironmentDetector = class {
|
|
3
144
|
detect() {
|
|
@@ -4328,6 +4469,11 @@ export class User extends Model {
|
|
|
4328
4469
|
// ─────────────────────────────────────────────────────────────
|
|
4329
4470
|
// Action Generators
|
|
4330
4471
|
// ─────────────────────────────────────────────────────────────
|
|
4472
|
+
/**
|
|
4473
|
+
* Generates the base Action class source code.
|
|
4474
|
+
*
|
|
4475
|
+
* @returns The complete source code for the abstract Action class.
|
|
4476
|
+
*/
|
|
4331
4477
|
generateActionBase() {
|
|
4332
4478
|
return `/**
|
|
4333
4479
|
* Action Base Class
|
|
@@ -4344,6 +4490,11 @@ export abstract class Action<TInput = unknown, TOutput = unknown> {
|
|
|
4344
4490
|
}
|
|
4345
4491
|
`;
|
|
4346
4492
|
}
|
|
4493
|
+
/**
|
|
4494
|
+
* Generates the GetServerStatusAction source code.
|
|
4495
|
+
*
|
|
4496
|
+
* @returns The complete source code for the example action.
|
|
4497
|
+
*/
|
|
4347
4498
|
generateGetServerStatusAction() {
|
|
4348
4499
|
return `/**
|
|
4349
4500
|
* Get Server Status Action
|
|
@@ -4366,6 +4517,11 @@ export class GetServerStatusAction extends Action<void, ServerStatusResponse> {
|
|
|
4366
4517
|
// ─────────────────────────────────────────────────────────────
|
|
4367
4518
|
// Controller Generators
|
|
4368
4519
|
// ─────────────────────────────────────────────────────────────
|
|
4520
|
+
/**
|
|
4521
|
+
* Generates the Server Controller source code.
|
|
4522
|
+
*
|
|
4523
|
+
* @returns The complete source code for the ServerController class.
|
|
4524
|
+
*/
|
|
4369
4525
|
generateServerController() {
|
|
4370
4526
|
return `/**
|
|
4371
4527
|
* Server Controller
|
|
@@ -4393,6 +4549,11 @@ export class ServerController {
|
|
|
4393
4549
|
// ─────────────────────────────────────────────────────────────
|
|
4394
4550
|
// Type Generators
|
|
4395
4551
|
// ─────────────────────────────────────────────────────────────
|
|
4552
|
+
/**
|
|
4553
|
+
* Generates the ServerStatusResponse type definition.
|
|
4554
|
+
*
|
|
4555
|
+
* @returns The complete source code for the response interface.
|
|
4556
|
+
*/
|
|
4396
4557
|
generateServerStatusResponse() {
|
|
4397
4558
|
return `/**
|
|
4398
4559
|
* Server Status Response Type
|
|
@@ -4408,6 +4569,11 @@ export interface ServerStatusResponse {
|
|
|
4408
4569
|
// ─────────────────────────────────────────────────────────────
|
|
4409
4570
|
// Routes & Bootstrap
|
|
4410
4571
|
// ─────────────────────────────────────────────────────────────
|
|
4572
|
+
/**
|
|
4573
|
+
* Generates the API routes registration function.
|
|
4574
|
+
*
|
|
4575
|
+
* @returns The complete source code for the api.ts routes file.
|
|
4576
|
+
*/
|
|
4411
4577
|
generateApiRoutes() {
|
|
4412
4578
|
return `/**
|
|
4413
4579
|
* API Routes Registration
|
|
@@ -4426,6 +4592,12 @@ export function registerApiRoutes(router: Router) {
|
|
|
4426
4592
|
}
|
|
4427
4593
|
`;
|
|
4428
4594
|
}
|
|
4595
|
+
/**
|
|
4596
|
+
* Generates the App Service Provider source code.
|
|
4597
|
+
*
|
|
4598
|
+
* @param context - The generator context containing project details.
|
|
4599
|
+
* @returns The complete source code for AppServiceProvider.
|
|
4600
|
+
*/
|
|
4429
4601
|
generateAppServiceProvider(context) {
|
|
4430
4602
|
return `/**
|
|
4431
4603
|
* App Service Provider
|
|
@@ -4454,6 +4626,11 @@ export { MiddlewareProvider } from './MiddlewareProvider'
|
|
|
4454
4626
|
export { RouteProvider } from './RouteProvider'
|
|
4455
4627
|
`;
|
|
4456
4628
|
}
|
|
4629
|
+
/**
|
|
4630
|
+
* Generates the Middleware Service Provider source code.
|
|
4631
|
+
*
|
|
4632
|
+
* @returns The complete source code for MiddlewareProvider.
|
|
4633
|
+
*/
|
|
4457
4634
|
generateMiddlewareProvider() {
|
|
4458
4635
|
return `/**
|
|
4459
4636
|
* Middleware Service Provider
|
|
@@ -4478,6 +4655,11 @@ export class MiddlewareProvider extends ServiceProvider {
|
|
|
4478
4655
|
}
|
|
4479
4656
|
`;
|
|
4480
4657
|
}
|
|
4658
|
+
/**
|
|
4659
|
+
* Generates the Route Service Provider source code.
|
|
4660
|
+
*
|
|
4661
|
+
* @returns The complete source code for RouteProvider.
|
|
4662
|
+
*/
|
|
4481
4663
|
generateRouteProvider() {
|
|
4482
4664
|
return `/**
|
|
4483
4665
|
* Route Service Provider
|
|
@@ -4865,6 +5047,7 @@ export {
|
|
|
4865
5047
|
BaseGenerator,
|
|
4866
5048
|
CleanArchitectureGenerator,
|
|
4867
5049
|
DddGenerator,
|
|
5050
|
+
DependencyValidator,
|
|
4868
5051
|
EnterpriseMvcGenerator,
|
|
4869
5052
|
EnvironmentDetector,
|
|
4870
5053
|
FileMerger,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravito/scaffold",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Project scaffolding engine for Gravito - Generate enterprise-grade architecture templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "bun run build.ts",
|
|
18
18
|
"dev": "bun run --watch src/index.ts",
|
|
19
|
-
"test": "bun test",
|
|
19
|
+
"test": "bun test --timeout=10000",
|
|
20
20
|
"typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
|
|
21
|
-
"test:coverage": "bun test --coverage --coverage-
|
|
22
|
-
"test:ci": "bun test --coverage --coverage-
|
|
21
|
+
"test:coverage": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
|
|
22
|
+
"test:ci": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
|
|
23
|
+
"test:unit": "bun test tests/ --timeout=10000",
|
|
24
|
+
"test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'"
|
|
23
25
|
},
|
|
24
26
|
"files": [
|
|
25
27
|
"dist",
|
|
@@ -48,4 +50,4 @@
|
|
|
48
50
|
"url": "git+https://github.com/gravito-framework/gravito.git",
|
|
49
51
|
"directory": "packages/scaffold"
|
|
50
52
|
}
|
|
51
|
-
}
|
|
53
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"@opentelemetry/sdk-node": "^0.45.0",
|
|
4
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.45.0",
|
|
5
|
+
"@gravito/telemetry": "workspace:*"
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"ioredis": "^5.3.0"
|
|
4
|
+
}
|
|
5
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"better-sqlite3": "^9.0.0"
|
|
4
|
+
}
|
|
5
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"ioredis": "^5.0.0",
|
|
4
|
+
"pg": "^8.0.0",
|
|
5
|
+
"@gravito/spectrum": "workspace:*"
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
2
|
+
"dependencies": {
|
|
3
|
+
"ioredis": "^5.0.0",
|
|
4
|
+
"pg": "^8.0.0"
|
|
5
|
+
}
|
|
6
|
+
}
|