opticore-feature-component 1.0.5 → 1.0.6
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/{core-GNR24GXE.js → core-TFP6J3AE.js} +705 -19
- package/dist/index.cjs +740 -20
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/core/core.ts
|
|
2
2
|
import process3 from "process";
|
|
3
3
|
import fs5 from "fs";
|
|
4
|
-
import
|
|
5
|
-
import { isCancel as
|
|
4
|
+
import path9 from "path";
|
|
5
|
+
import { isCancel as isCancel7 } from "@clack/prompts";
|
|
6
6
|
|
|
7
7
|
// src/utils/welcomeMessage.utils.ts
|
|
8
8
|
import cfonts from "cfonts";
|
|
@@ -126,7 +126,9 @@ async function choiceFeatureCleanModule() {
|
|
|
126
126
|
["opticore_principle"],
|
|
127
127
|
[
|
|
128
128
|
{ label: "OptiCoreJs CLEAN Module", value: ["opticore_clean_module"], hint: "recommended" },
|
|
129
|
-
{ label: "
|
|
129
|
+
{ label: "MVC Architecture", value: ["mvc_architecture"] },
|
|
130
|
+
{ label: "Layered Architecture", value: ["layered_architecture"] },
|
|
131
|
+
{ label: "Build your own architecture", value: ["custom_feature"] }
|
|
130
132
|
]
|
|
131
133
|
);
|
|
132
134
|
if (isCancel(featureSelected)) {
|
|
@@ -877,19 +879,19 @@ var generateRouterHandlerTemplate = (featureName, controllerMethods) => {
|
|
|
877
879
|
const handlerName = `${capitalized}HandlerRouter`;
|
|
878
880
|
const controllerName = `${capitalized}Controller`;
|
|
879
881
|
const routesCode = (controllerMethods || []).map((method) => {
|
|
880
|
-
const { httpMethod, path:
|
|
882
|
+
const { httpMethod, path: path10 } = resolveRoute(method, featureName);
|
|
881
883
|
return `{
|
|
882
|
-
path: \`${
|
|
884
|
+
path: \`${path10}\`,
|
|
883
885
|
method: "${httpMethod}",
|
|
884
886
|
middlewares: [],
|
|
885
887
|
handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
|
|
886
888
|
}`;
|
|
887
889
|
}).join(",\n");
|
|
888
|
-
return `import {
|
|
890
|
+
return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
889
891
|
import { ${controllerName} } from "../adapters/controllers/${featureName}.controller";
|
|
890
892
|
|
|
891
893
|
export const ${handlerName}: () => IMultipleRouteDefinition = () => {
|
|
892
|
-
return
|
|
894
|
+
return OpticoreRoutingFactory.routes(
|
|
893
895
|
${controllerName},
|
|
894
896
|
[
|
|
895
897
|
${routesCode.replace(/\n/g, "\n ")}
|
|
@@ -1397,19 +1399,19 @@ var generateSimpleRouterHandlerTemplate = (featureName, controllerMethods) => {
|
|
|
1397
1399
|
const handlerName = `${capitalized}HandlerRouter`;
|
|
1398
1400
|
const controllerName = `${capitalized}Controller`;
|
|
1399
1401
|
const routesCode = (controllerMethods || []).map((method) => {
|
|
1400
|
-
const { httpMethod, path:
|
|
1402
|
+
const { httpMethod, path: path10 } = resolveRoute2(method, featureName);
|
|
1401
1403
|
return `{
|
|
1402
|
-
path: \`${
|
|
1404
|
+
path: \`${path10}\`,
|
|
1403
1405
|
method: "${httpMethod}",
|
|
1404
1406
|
middlewares: [],
|
|
1405
1407
|
handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
|
|
1406
1408
|
}`;
|
|
1407
1409
|
}).join(",\n");
|
|
1408
|
-
return `import {
|
|
1410
|
+
return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
1409
1411
|
import { ${controllerName} } from "../controllers/${featureName}.controller";
|
|
1410
1412
|
|
|
1411
1413
|
export const ${handlerName}: () => IMultipleRouteDefinition = () => {
|
|
1412
|
-
return
|
|
1414
|
+
return OpticoreRoutingFactory.routes(
|
|
1413
1415
|
${controllerName},
|
|
1414
1416
|
[
|
|
1415
1417
|
${routesCode.replace(/\n/g, "\n ")}
|
|
@@ -1647,7 +1649,7 @@ export class ${controllerName} {}
|
|
|
1647
1649
|
*/
|
|
1648
1650
|
static async updateRegisterRouter(featureName) {
|
|
1649
1651
|
const routerName = `${this.capitalize(featureName)}Router`;
|
|
1650
|
-
const routerPath = this.structure === "simple" ? `../../features/${featureName}/routes/${featureName}.router` : this.structure === "custom" ? `../../features/${featureName}/${featureName}.router` : `../../features/${featureName}/infrastructure/routes/${featureName}.router`;
|
|
1652
|
+
const routerPath = this.structure === "simple" || this.structure === "mvc" || this.structure === "layered" ? `../../features/${featureName}/routes/${featureName}.router` : this.structure === "custom" ? `../../features/${featureName}/${featureName}.router` : `../../features/${featureName}/infrastructure/routes/${featureName}.router`;
|
|
1651
1653
|
const importStatement = `import { ${routerName} } from "${routerPath}"`;
|
|
1652
1654
|
try {
|
|
1653
1655
|
if (!fs3.existsSync(this.REGISTER_ROUTER_PATH)) {
|
|
@@ -2142,19 +2144,19 @@ var generateCustomRouterHandlerTemplate = (moduleName, controllerMethods) => {
|
|
|
2142
2144
|
const handlerName = `${cap}HandlerRouter`;
|
|
2143
2145
|
const controllerName = `${cap}Controller`;
|
|
2144
2146
|
const routesCode = (controllerMethods || []).map((method) => {
|
|
2145
|
-
const { httpMethod, path:
|
|
2147
|
+
const { httpMethod, path: path10 } = CResolveRoute(method, moduleName);
|
|
2146
2148
|
return `{
|
|
2147
|
-
path: \`${
|
|
2149
|
+
path: \`${path10}\`,
|
|
2148
2150
|
method: "${httpMethod}",
|
|
2149
2151
|
middlewares: [],
|
|
2150
2152
|
handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
|
|
2151
2153
|
}`;
|
|
2152
2154
|
}).join(",\n");
|
|
2153
|
-
return `import {
|
|
2155
|
+
return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
2154
2156
|
import { ${controllerName} } from "../../app/${moduleName}.controller";
|
|
2155
2157
|
|
|
2156
2158
|
export const ${handlerName}: () => IMultipleRouteDefinition = () => {
|
|
2157
|
-
return
|
|
2159
|
+
return OpticoreRoutingFactory.routes(
|
|
2158
2160
|
${controllerName},
|
|
2159
2161
|
[
|
|
2160
2162
|
${routesCode ? routesCode.replace(/\n/g, "\n ") : ""}
|
|
@@ -2290,6 +2292,668 @@ ${colors9.bgGreen(colors9.white(`
|
|
|
2290
2292
|
`))}`);
|
|
2291
2293
|
};
|
|
2292
2294
|
|
|
2295
|
+
// src/templates/mvcModule/mvcModuleScaffold.template.ts
|
|
2296
|
+
import path7 from "path";
|
|
2297
|
+
import colors10 from "ansi-colors";
|
|
2298
|
+
import { isCancel as isCancel5 } from "@clack/prompts";
|
|
2299
|
+
|
|
2300
|
+
// src/templates/mvcModule/mvcModule.template.ts
|
|
2301
|
+
var capitalize19 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2302
|
+
var generateMvcModelTemplate = (featureName) => {
|
|
2303
|
+
const capitalized = capitalize19(featureName);
|
|
2304
|
+
const modelName = `${capitalized}Model`;
|
|
2305
|
+
return `/**
|
|
2306
|
+
* ${modelName} \u2014 Model
|
|
2307
|
+
* Owns both the data shape and the data-access logic for "${featureName}".
|
|
2308
|
+
*/
|
|
2309
|
+
export class ${modelName} {
|
|
2310
|
+
id: string;
|
|
2311
|
+
createdAt: Date;
|
|
2312
|
+
updatedAt: Date;
|
|
2313
|
+
|
|
2314
|
+
constructor(
|
|
2315
|
+
id: string,
|
|
2316
|
+
// TODO: add your model properties here
|
|
2317
|
+
createdAt?: Date,
|
|
2318
|
+
updatedAt?: Date,
|
|
2319
|
+
) {
|
|
2320
|
+
this.id = id;
|
|
2321
|
+
this.createdAt = createdAt ?? new Date();
|
|
2322
|
+
this.updatedAt = updatedAt ?? new Date();
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
private static store: Map<string, ${modelName}> = new Map();
|
|
2326
|
+
|
|
2327
|
+
static async findAll(): Promise<${modelName}[]> {
|
|
2328
|
+
// TODO: Replace with your ORM query
|
|
2329
|
+
return Array.from(this.store.values());
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
static async findById(id: string): Promise<${modelName} | null> {
|
|
2333
|
+
// TODO: Replace with your ORM query
|
|
2334
|
+
return this.store.get(id) ?? null;
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
static async create(data: Record<string, unknown>): Promise<${modelName}> {
|
|
2338
|
+
const model = new ${modelName}(String(Date.now()));
|
|
2339
|
+
// TODO: Map data fields onto model
|
|
2340
|
+
this.store.set(model.id, model);
|
|
2341
|
+
return model;
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
static async update(id: string, data: Record<string, unknown>): Promise<${modelName} | null> {
|
|
2345
|
+
const existing = this.store.get(id);
|
|
2346
|
+
if (!existing) return null;
|
|
2347
|
+
// TODO: Apply data fields onto existing model
|
|
2348
|
+
existing.updatedAt = new Date();
|
|
2349
|
+
this.store.set(id, existing);
|
|
2350
|
+
return existing;
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
static async delete(id: string): Promise<boolean> {
|
|
2354
|
+
// TODO: Replace with your ORM delete
|
|
2355
|
+
return this.store.delete(id);
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
`;
|
|
2359
|
+
};
|
|
2360
|
+
var generateMvcViewTemplate = (featureName) => {
|
|
2361
|
+
const capitalized = capitalize19(featureName);
|
|
2362
|
+
const modelName = `${capitalized}Model`;
|
|
2363
|
+
const viewName = `${capitalized}View`;
|
|
2364
|
+
return `import { ${modelName} } from "../models/${featureName}.model";
|
|
2365
|
+
|
|
2366
|
+
/**
|
|
2367
|
+
* ${viewName} \u2014 View
|
|
2368
|
+
* Shapes "${featureName}" data before it is sent back as JSON.
|
|
2369
|
+
*/
|
|
2370
|
+
export class ${viewName} {
|
|
2371
|
+
static toJSON(model: ${modelName}): Record<string, unknown> {
|
|
2372
|
+
return {
|
|
2373
|
+
id: model.id,
|
|
2374
|
+
createdAt: model.createdAt,
|
|
2375
|
+
updatedAt: model.updatedAt,
|
|
2376
|
+
// TODO: expose the fields API consumers should see (and only those)
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
static toJSONList(models: ${modelName}[]): Record<string, unknown>[] {
|
|
2381
|
+
return models.map((model: ${modelName}): Record<string, unknown> => this.toJSON(model));
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
`;
|
|
2385
|
+
};
|
|
2386
|
+
var generateMvcControllerTemplate = (controllerName, featureName, methods) => {
|
|
2387
|
+
const capitalized = capitalize19(featureName);
|
|
2388
|
+
const modelName = `${capitalized}Model`;
|
|
2389
|
+
const viewName = `${capitalized}View`;
|
|
2390
|
+
const methodsCode = methods.map((method) => generateMethod4(method, capitalized, modelName, viewName)).join("\n");
|
|
2391
|
+
return `import { Request, Response } from "opticore-express";
|
|
2392
|
+
import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
|
|
2393
|
+
import { ${modelName} } from "../models/${featureName}.model";
|
|
2394
|
+
import { ${viewName} } from "../views/${featureName}.view";
|
|
2395
|
+
|
|
2396
|
+
export class ${controllerName} {
|
|
2397
|
+
${methodsCode}
|
|
2398
|
+
private static handleError(error: unknown) {
|
|
2399
|
+
const message = error instanceof Error ? error.message : "Internal server error";
|
|
2400
|
+
return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
`;
|
|
2404
|
+
};
|
|
2405
|
+
var generateMethod4 = (method, capitalized, modelName, viewName) => {
|
|
2406
|
+
const lower = method.toLowerCase();
|
|
2407
|
+
if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod3(method, capitalized, modelName, viewName);
|
|
2408
|
+
if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod3(method, capitalized, modelName, viewName);
|
|
2409
|
+
if (lower.includes("create") || lower.includes("add")) return generateCreateMethod3(method, capitalized, modelName, viewName);
|
|
2410
|
+
if (lower.includes("update") || lower.includes("edit")) return generateUpdateMethod3(method, capitalized, modelName, viewName);
|
|
2411
|
+
if (lower.includes("delete") || lower.includes("remove")) return generateDeleteMethod3(method, capitalized, modelName);
|
|
2412
|
+
return `
|
|
2413
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2414
|
+
try {
|
|
2415
|
+
// TODO: Implement ${method} logic
|
|
2416
|
+
return ResponseHandler.success({}, "success", HttpStatusCode.OK);
|
|
2417
|
+
} catch (error) {
|
|
2418
|
+
return ${capitalized}Controller.handleError(error);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
`;
|
|
2422
|
+
};
|
|
2423
|
+
var generateFindAllMethod3 = (method, capitalized, modelName, viewName) => `
|
|
2424
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2425
|
+
try {
|
|
2426
|
+
const models = await ${modelName}.findAll();
|
|
2427
|
+
return ResponseHandler.success(${viewName}.toJSONList(models), "success", HttpStatusCode.OK);
|
|
2428
|
+
} catch (error) {
|
|
2429
|
+
return ${capitalized}Controller.handleError(error);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
`;
|
|
2433
|
+
var generateFindByIdMethod3 = (method, capitalized, modelName, viewName) => `
|
|
2434
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2435
|
+
try {
|
|
2436
|
+
const { id } = req.params;
|
|
2437
|
+
const model = await ${modelName}.findById(id);
|
|
2438
|
+
if (!model) {
|
|
2439
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2440
|
+
}
|
|
2441
|
+
return ResponseHandler.success(${viewName}.toJSON(model), "success", HttpStatusCode.OK);
|
|
2442
|
+
} catch (error) {
|
|
2443
|
+
return ${capitalized}Controller.handleError(error);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
`;
|
|
2447
|
+
var generateCreateMethod3 = (method, capitalized, modelName, viewName) => `
|
|
2448
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2449
|
+
try {
|
|
2450
|
+
const model = await ${modelName}.create(req.body);
|
|
2451
|
+
return ResponseHandler.success(${viewName}.toJSON(model), "created", HttpStatusCode.CREATED);
|
|
2452
|
+
} catch (error) {
|
|
2453
|
+
return ${capitalized}Controller.handleError(error);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
`;
|
|
2457
|
+
var generateUpdateMethod3 = (method, capitalized, modelName, viewName) => `
|
|
2458
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2459
|
+
try {
|
|
2460
|
+
const { id } = req.params;
|
|
2461
|
+
const model = await ${modelName}.update(id, req.body);
|
|
2462
|
+
if (!model) {
|
|
2463
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2464
|
+
}
|
|
2465
|
+
return ResponseHandler.success(${viewName}.toJSON(model), "success", HttpStatusCode.OK);
|
|
2466
|
+
} catch (error) {
|
|
2467
|
+
return ${capitalized}Controller.handleError(error);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
`;
|
|
2471
|
+
var generateDeleteMethod3 = (method, capitalized, modelName) => `
|
|
2472
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2473
|
+
try {
|
|
2474
|
+
const { id } = req.params;
|
|
2475
|
+
const deleted = await ${modelName}.delete(id);
|
|
2476
|
+
if (!deleted) {
|
|
2477
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2478
|
+
}
|
|
2479
|
+
return ResponseHandler.success(null, "deleted", HttpStatusCode.NO_CONTENT);
|
|
2480
|
+
} catch (error) {
|
|
2481
|
+
return ${capitalized}Controller.handleError(error);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
`;
|
|
2485
|
+
var generateMvcRouterHandlerTemplate = (featureName, controllerMethods) => {
|
|
2486
|
+
const capitalized = capitalize19(featureName);
|
|
2487
|
+
const handlerName = `${capitalized}HandlerRouter`;
|
|
2488
|
+
const controllerName = `${capitalized}Controller`;
|
|
2489
|
+
const routesCode = (controllerMethods || []).map((method) => {
|
|
2490
|
+
const { httpMethod, path: path10 } = resolveRoute3(method, featureName);
|
|
2491
|
+
return `{
|
|
2492
|
+
path: \`${path10}\`,
|
|
2493
|
+
method: "${httpMethod}",
|
|
2494
|
+
middlewares: [],
|
|
2495
|
+
handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
|
|
2496
|
+
}`;
|
|
2497
|
+
}).join(",\n");
|
|
2498
|
+
return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
2499
|
+
import { ${controllerName} } from "../controllers/${featureName}.controller";
|
|
2500
|
+
|
|
2501
|
+
export const ${handlerName}: () => IMultipleRouteDefinition = () => {
|
|
2502
|
+
return OpticoreRoutingFactory.routes(
|
|
2503
|
+
${controllerName},
|
|
2504
|
+
[
|
|
2505
|
+
${routesCode.replace(/\n/g, "\n ")}
|
|
2506
|
+
]
|
|
2507
|
+
);
|
|
2508
|
+
};
|
|
2509
|
+
`;
|
|
2510
|
+
};
|
|
2511
|
+
var generateMvcRouterTemplate = (featureName) => {
|
|
2512
|
+
const capitalized = capitalize19(featureName);
|
|
2513
|
+
const handlerName = `${capitalized}HandlerRouter`;
|
|
2514
|
+
const routerName = `${capitalized}Router`;
|
|
2515
|
+
return `import { ${handlerName} } from "./${featureName}.router.handler";
|
|
2516
|
+
import { TFeatureRoutes } from "opticore-router";
|
|
2517
|
+
|
|
2518
|
+
export const ${routerName}: TFeatureRoutes = {
|
|
2519
|
+
routes: [
|
|
2520
|
+
{
|
|
2521
|
+
path: ${handlerName}().path,
|
|
2522
|
+
handler: ${handlerName}().handler
|
|
2523
|
+
}
|
|
2524
|
+
]
|
|
2525
|
+
};
|
|
2526
|
+
`;
|
|
2527
|
+
};
|
|
2528
|
+
var resolveRoute3 = (methodName, featureName) => {
|
|
2529
|
+
const lower = methodName.toLowerCase();
|
|
2530
|
+
if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
|
|
2531
|
+
if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
|
|
2532
|
+
if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
|
|
2533
|
+
if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
|
|
2534
|
+
if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
|
|
2535
|
+
return { httpMethod: "get", path: `/${featureName}/${lower}` };
|
|
2536
|
+
};
|
|
2537
|
+
|
|
2538
|
+
// src/templates/mvcModule/mvcModuleScaffold.template.ts
|
|
2539
|
+
var capitalize20 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2540
|
+
var mvcModuleTemplate = async (featureName) => {
|
|
2541
|
+
FeatureComponentGeneratorUtils.setStructure("mvc");
|
|
2542
|
+
const basePath = path7.join("src", "features", featureName);
|
|
2543
|
+
const paths = {
|
|
2544
|
+
modelsDir: path7.join(basePath, "models"),
|
|
2545
|
+
viewsDir: path7.join(basePath, "views"),
|
|
2546
|
+
controllersDir: path7.join(basePath, "controllers"),
|
|
2547
|
+
routesDir: path7.join(basePath, "routes")
|
|
2548
|
+
};
|
|
2549
|
+
Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
|
|
2550
|
+
const controllerName = `${capitalize20(featureName)}Controller`;
|
|
2551
|
+
UFsModule.createFile(path7.join(paths.modelsDir, `${featureName}.model.ts`), generateMvcModelTemplate(featureName));
|
|
2552
|
+
console.log(colors10.green(`\u2705 Model created: ${path7.join(paths.modelsDir, `${featureName}.model.ts`)}`));
|
|
2553
|
+
UFsModule.createFile(path7.join(paths.viewsDir, `${featureName}.view.ts`), generateMvcViewTemplate(featureName));
|
|
2554
|
+
console.log(colors10.green(`\u2705 View created: ${path7.join(paths.viewsDir, `${featureName}.view.ts`)}`));
|
|
2555
|
+
const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
|
|
2556
|
+
let methods = [];
|
|
2557
|
+
let controllerContent;
|
|
2558
|
+
if (wantsMethods && !isCancel5(wantsMethods)) {
|
|
2559
|
+
const methodsText = await UPrompt.text(
|
|
2560
|
+
"Enter the method names (comma separated):",
|
|
2561
|
+
"create, findAll, findById, update, delete",
|
|
2562
|
+
(v) => v ? void 0 : "You must enter at least one method."
|
|
2563
|
+
);
|
|
2564
|
+
methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
|
|
2565
|
+
controllerContent = generateMvcControllerTemplate(controllerName, featureName, methods);
|
|
2566
|
+
} else {
|
|
2567
|
+
controllerContent = `import { Request, Response } from "opticore-express";
|
|
2568
|
+
|
|
2569
|
+
export class ${controllerName} {}
|
|
2570
|
+
`;
|
|
2571
|
+
}
|
|
2572
|
+
const controllerPath = path7.join(paths.controllersDir, `${featureName}.controller.ts`);
|
|
2573
|
+
UFsModule.createFile(controllerPath, controllerContent);
|
|
2574
|
+
console.log(colors10.green(`\u2705 Controller created: ${controllerPath}`));
|
|
2575
|
+
UFsModule.createFile(
|
|
2576
|
+
path7.join(paths.routesDir, `${featureName}.router.handler.ts`),
|
|
2577
|
+
generateMvcRouterHandlerTemplate(featureName, methods)
|
|
2578
|
+
);
|
|
2579
|
+
console.log(colors10.green(`\u2705 Router Handler created: ${path7.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
|
|
2580
|
+
UFsModule.createFile(
|
|
2581
|
+
path7.join(paths.routesDir, `${featureName}.router.ts`),
|
|
2582
|
+
generateMvcRouterTemplate(featureName)
|
|
2583
|
+
);
|
|
2584
|
+
await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
|
|
2585
|
+
console.log(colors10.green(`\u2705 Router created: ${path7.join(paths.routesDir, `${featureName}.router.ts`)}`));
|
|
2586
|
+
console.log(
|
|
2587
|
+
colors10.bgGreen(
|
|
2588
|
+
colors10.white(`
|
|
2589
|
+
\u{1F389} Feature "${featureName}" scaffolded with MVC architecture!
|
|
2590
|
+
`)
|
|
2591
|
+
)
|
|
2592
|
+
);
|
|
2593
|
+
};
|
|
2594
|
+
|
|
2595
|
+
// src/templates/layeredModule/layeredModuleScaffold.template.ts
|
|
2596
|
+
import path8 from "path";
|
|
2597
|
+
import colors11 from "ansi-colors";
|
|
2598
|
+
import { isCancel as isCancel6 } from "@clack/prompts";
|
|
2599
|
+
|
|
2600
|
+
// src/templates/layeredModule/layeredModule.template.ts
|
|
2601
|
+
var capitalize21 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2602
|
+
var generateLayeredEntityTemplate = (featureName) => {
|
|
2603
|
+
const capitalized = capitalize21(featureName);
|
|
2604
|
+
const entityName = `${capitalized}Entity`;
|
|
2605
|
+
return `/**
|
|
2606
|
+
* ${entityName} \u2014 Entity
|
|
2607
|
+
* Plain data structure for the "${featureName}" domain. No data-access logic here.
|
|
2608
|
+
*/
|
|
2609
|
+
export class ${entityName} {
|
|
2610
|
+
constructor(
|
|
2611
|
+
public readonly id: string,
|
|
2612
|
+
// TODO: add your entity fields here
|
|
2613
|
+
public readonly createdAt: Date = new Date(),
|
|
2614
|
+
public readonly updatedAt: Date = new Date(),
|
|
2615
|
+
) {}
|
|
2616
|
+
}
|
|
2617
|
+
`;
|
|
2618
|
+
};
|
|
2619
|
+
var generateLayeredDtoTemplate = (featureName) => {
|
|
2620
|
+
const capitalized = capitalize21(featureName);
|
|
2621
|
+
const entityName = `${capitalized}Entity`;
|
|
2622
|
+
return `import { ${entityName} } from "../entities/${featureName}.entity";
|
|
2623
|
+
|
|
2624
|
+
export interface Create${capitalized}Dto {
|
|
2625
|
+
// TODO: define the fields required to create a ${featureName}
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
export interface Update${capitalized}Dto {
|
|
2629
|
+
// TODO: define the fields that can be updated
|
|
2630
|
+
}
|
|
2631
|
+
|
|
2632
|
+
export interface ${capitalized}ResponseDto {
|
|
2633
|
+
id: string;
|
|
2634
|
+
createdAt: Date;
|
|
2635
|
+
updatedAt: Date;
|
|
2636
|
+
// TODO: define the fields exposed to API consumers
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
export const to${capitalized}ResponseDto = (entity: ${entityName}): ${capitalized}ResponseDto => ({
|
|
2640
|
+
id: entity.id,
|
|
2641
|
+
createdAt: entity.createdAt,
|
|
2642
|
+
updatedAt: entity.updatedAt,
|
|
2643
|
+
});
|
|
2644
|
+
`;
|
|
2645
|
+
};
|
|
2646
|
+
var generateLayeredRepositoryTemplate = (featureName) => {
|
|
2647
|
+
const capitalized = capitalize21(featureName);
|
|
2648
|
+
const entityName = `${capitalized}Entity`;
|
|
2649
|
+
const repoName = `${capitalized}Repository`;
|
|
2650
|
+
return `import { ${entityName} } from "../entities/${featureName}.entity";
|
|
2651
|
+
|
|
2652
|
+
export class ${repoName} {
|
|
2653
|
+
private store: Map<string, ${entityName}> = new Map();
|
|
2654
|
+
|
|
2655
|
+
async findAll(): Promise<${entityName}[]> {
|
|
2656
|
+
// TODO: Replace with your ORM query
|
|
2657
|
+
return Array.from(this.store.values());
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
async findById(id: string): Promise<${entityName} | null> {
|
|
2661
|
+
// TODO: Replace with your ORM query
|
|
2662
|
+
return this.store.get(id) ?? null;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
async create(entity: ${entityName}): Promise<${entityName}> {
|
|
2666
|
+
// TODO: Replace with your ORM save
|
|
2667
|
+
this.store.set(entity.id, entity);
|
|
2668
|
+
return entity;
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
async update(entity: ${entityName}): Promise<${entityName} | null> {
|
|
2672
|
+
// TODO: Replace with your ORM update
|
|
2673
|
+
if (!this.store.has(entity.id)) return null;
|
|
2674
|
+
this.store.set(entity.id, entity);
|
|
2675
|
+
return entity;
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2678
|
+
async delete(id: string): Promise<boolean> {
|
|
2679
|
+
// TODO: Replace with your ORM delete
|
|
2680
|
+
return this.store.delete(id);
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
`;
|
|
2684
|
+
};
|
|
2685
|
+
var generateLayeredServiceTemplate = (featureName) => {
|
|
2686
|
+
const capitalized = capitalize21(featureName);
|
|
2687
|
+
const entityName = `${capitalized}Entity`;
|
|
2688
|
+
const repoName = `${capitalized}Repository`;
|
|
2689
|
+
const serviceName = `${capitalized}Service`;
|
|
2690
|
+
return `import { ${repoName} } from "../repositories/${featureName}.repository";
|
|
2691
|
+
import { ${entityName} } from "../entities/${featureName}.entity";
|
|
2692
|
+
import { Create${capitalized}Dto, Update${capitalized}Dto, ${capitalized}ResponseDto, to${capitalized}ResponseDto } from "../dto/${featureName}.dto";
|
|
2693
|
+
|
|
2694
|
+
export class ${serviceName} {
|
|
2695
|
+
private readonly repository: ${repoName};
|
|
2696
|
+
|
|
2697
|
+
constructor() {
|
|
2698
|
+
this.repository = new ${repoName}();
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
async findAll(): Promise<${capitalized}ResponseDto[]> {
|
|
2702
|
+
const entities = await this.repository.findAll();
|
|
2703
|
+
return entities.map(to${capitalized}ResponseDto);
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
async findById(id: string): Promise<${capitalized}ResponseDto | null> {
|
|
2707
|
+
const entity = await this.repository.findById(id);
|
|
2708
|
+
return entity ? to${capitalized}ResponseDto(entity) : null;
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
async create(data: Create${capitalized}Dto): Promise<${capitalized}ResponseDto> {
|
|
2712
|
+
const entity = new ${entityName}(String(Date.now()));
|
|
2713
|
+
// TODO: Map data fields onto entity
|
|
2714
|
+
const created = await this.repository.create(entity);
|
|
2715
|
+
return to${capitalized}ResponseDto(created);
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
async update(id: string, data: Update${capitalized}Dto): Promise<${capitalized}ResponseDto | null> {
|
|
2719
|
+
const existing = await this.repository.findById(id);
|
|
2720
|
+
if (!existing) {
|
|
2721
|
+
return null;
|
|
2722
|
+
}
|
|
2723
|
+
// TODO: Apply data fields onto existing entity
|
|
2724
|
+
const updated = await this.repository.update(existing);
|
|
2725
|
+
return updated ? to${capitalized}ResponseDto(updated) : null;
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
async delete(id: string): Promise<boolean> {
|
|
2729
|
+
return this.repository.delete(id);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
`;
|
|
2733
|
+
};
|
|
2734
|
+
var generateLayeredControllerTemplate = (controllerName, featureName, methods) => {
|
|
2735
|
+
const capitalized = capitalize21(featureName);
|
|
2736
|
+
const serviceName = `${capitalized}Service`;
|
|
2737
|
+
const methodsCode = methods.map((method) => generateMethod5(method, capitalized, serviceName)).join("\n");
|
|
2738
|
+
return `import { Request, Response } from "opticore-express";
|
|
2739
|
+
import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
|
|
2740
|
+
import { ${serviceName} } from "../services/${featureName}.service";
|
|
2741
|
+
|
|
2742
|
+
export class ${controllerName} {
|
|
2743
|
+
private static buildService(): ${serviceName} {
|
|
2744
|
+
return new ${serviceName}();
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
${methodsCode}
|
|
2748
|
+
private static handleError(error: unknown) {
|
|
2749
|
+
const message = error instanceof Error ? error.message : "Internal server error";
|
|
2750
|
+
return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
`;
|
|
2754
|
+
};
|
|
2755
|
+
var generateMethod5 = (method, capitalized, serviceName) => {
|
|
2756
|
+
const lower = method.toLowerCase();
|
|
2757
|
+
if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod4(method, capitalized);
|
|
2758
|
+
if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod4(method, capitalized);
|
|
2759
|
+
if (lower.includes("create") || lower.includes("add")) return generateCreateMethod4(method, capitalized);
|
|
2760
|
+
if (lower.includes("update") || lower.includes("edit")) return generateUpdateMethod4(method, capitalized);
|
|
2761
|
+
if (lower.includes("delete") || lower.includes("remove")) return generateDeleteMethod4(method, capitalized);
|
|
2762
|
+
return `
|
|
2763
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2764
|
+
try {
|
|
2765
|
+
const service = ${capitalized}Controller.buildService();
|
|
2766
|
+
// TODO: Implement ${method} logic
|
|
2767
|
+
return ResponseHandler.success({}, "success", HttpStatusCode.OK);
|
|
2768
|
+
} catch (error) {
|
|
2769
|
+
return ${capitalized}Controller.handleError(error);
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
`;
|
|
2773
|
+
};
|
|
2774
|
+
var generateFindAllMethod4 = (method, capitalized) => `
|
|
2775
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2776
|
+
try {
|
|
2777
|
+
const service = ${capitalized}Controller.buildService();
|
|
2778
|
+
const results = await service.findAll();
|
|
2779
|
+
return ResponseHandler.success(results, "success", HttpStatusCode.OK);
|
|
2780
|
+
} catch (error) {
|
|
2781
|
+
return ${capitalized}Controller.handleError(error);
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
`;
|
|
2785
|
+
var generateFindByIdMethod4 = (method, capitalized) => `
|
|
2786
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2787
|
+
try {
|
|
2788
|
+
const { id } = req.params;
|
|
2789
|
+
const service = ${capitalized}Controller.buildService();
|
|
2790
|
+
const result = await service.findById(id);
|
|
2791
|
+
if (!result) {
|
|
2792
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2793
|
+
}
|
|
2794
|
+
return ResponseHandler.success(result, "success", HttpStatusCode.OK);
|
|
2795
|
+
} catch (error) {
|
|
2796
|
+
return ${capitalized}Controller.handleError(error);
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
`;
|
|
2800
|
+
var generateCreateMethod4 = (method, capitalized) => `
|
|
2801
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2802
|
+
try {
|
|
2803
|
+
const service = ${capitalized}Controller.buildService();
|
|
2804
|
+
const result = await service.create(req.body);
|
|
2805
|
+
return ResponseHandler.success(result, "created", HttpStatusCode.CREATED);
|
|
2806
|
+
} catch (error) {
|
|
2807
|
+
return ${capitalized}Controller.handleError(error);
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
`;
|
|
2811
|
+
var generateUpdateMethod4 = (method, capitalized) => `
|
|
2812
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2813
|
+
try {
|
|
2814
|
+
const { id } = req.params;
|
|
2815
|
+
const service = ${capitalized}Controller.buildService();
|
|
2816
|
+
const result = await service.update(id, req.body);
|
|
2817
|
+
if (!result) {
|
|
2818
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2819
|
+
}
|
|
2820
|
+
return ResponseHandler.success(result, "success", HttpStatusCode.OK);
|
|
2821
|
+
} catch (error) {
|
|
2822
|
+
return ${capitalized}Controller.handleError(error);
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
`;
|
|
2826
|
+
var generateDeleteMethod4 = (method, capitalized) => `
|
|
2827
|
+
static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
|
|
2828
|
+
try {
|
|
2829
|
+
const { id } = req.params;
|
|
2830
|
+
const service = ${capitalized}Controller.buildService();
|
|
2831
|
+
const deleted = await service.delete(id);
|
|
2832
|
+
if (!deleted) {
|
|
2833
|
+
return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
|
|
2834
|
+
}
|
|
2835
|
+
return ResponseHandler.success(null, "deleted", HttpStatusCode.NO_CONTENT);
|
|
2836
|
+
} catch (error) {
|
|
2837
|
+
return ${capitalized}Controller.handleError(error);
|
|
2838
|
+
}
|
|
2839
|
+
}
|
|
2840
|
+
`;
|
|
2841
|
+
var generateLayeredRouterHandlerTemplate = (featureName, controllerMethods) => {
|
|
2842
|
+
const capitalized = capitalize21(featureName);
|
|
2843
|
+
const handlerName = `${capitalized}HandlerRouter`;
|
|
2844
|
+
const controllerName = `${capitalized}Controller`;
|
|
2845
|
+
const routesCode = (controllerMethods || []).map((method) => {
|
|
2846
|
+
const { httpMethod, path: path10 } = resolveRoute4(method, featureName);
|
|
2847
|
+
return `{
|
|
2848
|
+
path: \`${path10}\`,
|
|
2849
|
+
method: "${httpMethod}",
|
|
2850
|
+
middlewares: [],
|
|
2851
|
+
handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
|
|
2852
|
+
}`;
|
|
2853
|
+
}).join(",\n");
|
|
2854
|
+
return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
|
|
2855
|
+
import { ${controllerName} } from "../controllers/${featureName}.controller";
|
|
2856
|
+
|
|
2857
|
+
export const ${handlerName}: () => IMultipleRouteDefinition = () => {
|
|
2858
|
+
return OpticoreRoutingFactory.routes(
|
|
2859
|
+
${controllerName},
|
|
2860
|
+
[
|
|
2861
|
+
${routesCode.replace(/\n/g, "\n ")}
|
|
2862
|
+
]
|
|
2863
|
+
);
|
|
2864
|
+
};
|
|
2865
|
+
`;
|
|
2866
|
+
};
|
|
2867
|
+
var generateLayeredRouterTemplate = (featureName) => {
|
|
2868
|
+
const capitalized = capitalize21(featureName);
|
|
2869
|
+
const handlerName = `${capitalized}HandlerRouter`;
|
|
2870
|
+
const routerName = `${capitalized}Router`;
|
|
2871
|
+
return `import { ${handlerName} } from "./${featureName}.router.handler";
|
|
2872
|
+
import { TFeatureRoutes } from "opticore-router";
|
|
2873
|
+
|
|
2874
|
+
export const ${routerName}: TFeatureRoutes = {
|
|
2875
|
+
routes: [
|
|
2876
|
+
{
|
|
2877
|
+
path: ${handlerName}().path,
|
|
2878
|
+
handler: ${handlerName}().handler
|
|
2879
|
+
}
|
|
2880
|
+
]
|
|
2881
|
+
};
|
|
2882
|
+
`;
|
|
2883
|
+
};
|
|
2884
|
+
var resolveRoute4 = (methodName, featureName) => {
|
|
2885
|
+
const lower = methodName.toLowerCase();
|
|
2886
|
+
if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
|
|
2887
|
+
if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
|
|
2888
|
+
if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
|
|
2889
|
+
if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
|
|
2890
|
+
if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
|
|
2891
|
+
return { httpMethod: "get", path: `/${featureName}/${lower}` };
|
|
2892
|
+
};
|
|
2893
|
+
|
|
2894
|
+
// src/templates/layeredModule/layeredModuleScaffold.template.ts
|
|
2895
|
+
var capitalize22 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
|
2896
|
+
var layeredModuleTemplate = async (featureName) => {
|
|
2897
|
+
FeatureComponentGeneratorUtils.setStructure("layered");
|
|
2898
|
+
const basePath = path8.join("src", "features", featureName);
|
|
2899
|
+
const paths = {
|
|
2900
|
+
entitiesDir: path8.join(basePath, "entities"),
|
|
2901
|
+
dtoDir: path8.join(basePath, "dto"),
|
|
2902
|
+
repositoriesDir: path8.join(basePath, "repositories"),
|
|
2903
|
+
servicesDir: path8.join(basePath, "services"),
|
|
2904
|
+
controllersDir: path8.join(basePath, "controllers"),
|
|
2905
|
+
routesDir: path8.join(basePath, "routes")
|
|
2906
|
+
};
|
|
2907
|
+
Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
|
|
2908
|
+
const controllerName = `${capitalize22(featureName)}Controller`;
|
|
2909
|
+
UFsModule.createFile(path8.join(paths.entitiesDir, `${featureName}.entity.ts`), generateLayeredEntityTemplate(featureName));
|
|
2910
|
+
console.log(colors11.green(`\u2705 Entity created: ${path8.join(paths.entitiesDir, `${featureName}.entity.ts`)}`));
|
|
2911
|
+
UFsModule.createFile(path8.join(paths.dtoDir, `${featureName}.dto.ts`), generateLayeredDtoTemplate(featureName));
|
|
2912
|
+
console.log(colors11.green(`\u2705 DTO created: ${path8.join(paths.dtoDir, `${featureName}.dto.ts`)}`));
|
|
2913
|
+
UFsModule.createFile(path8.join(paths.repositoriesDir, `${featureName}.repository.ts`), generateLayeredRepositoryTemplate(featureName));
|
|
2914
|
+
console.log(colors11.green(`\u2705 Repository created: ${path8.join(paths.repositoriesDir, `${featureName}.repository.ts`)}`));
|
|
2915
|
+
UFsModule.createFile(path8.join(paths.servicesDir, `${featureName}.service.ts`), generateLayeredServiceTemplate(featureName));
|
|
2916
|
+
console.log(colors11.green(`\u2705 Service created: ${path8.join(paths.servicesDir, `${featureName}.service.ts`)}`));
|
|
2917
|
+
const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
|
|
2918
|
+
let methods = [];
|
|
2919
|
+
let controllerContent;
|
|
2920
|
+
if (wantsMethods && !isCancel6(wantsMethods)) {
|
|
2921
|
+
const methodsText = await UPrompt.text(
|
|
2922
|
+
"Enter the method names (comma separated):",
|
|
2923
|
+
"create, findAll, findById, update, delete",
|
|
2924
|
+
(v) => v ? void 0 : "You must enter at least one method."
|
|
2925
|
+
);
|
|
2926
|
+
methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
|
|
2927
|
+
controllerContent = generateLayeredControllerTemplate(controllerName, featureName, methods);
|
|
2928
|
+
} else {
|
|
2929
|
+
controllerContent = `import { Request, Response } from "opticore-express";
|
|
2930
|
+
|
|
2931
|
+
export class ${controllerName} {}
|
|
2932
|
+
`;
|
|
2933
|
+
}
|
|
2934
|
+
const controllerPath = path8.join(paths.controllersDir, `${featureName}.controller.ts`);
|
|
2935
|
+
UFsModule.createFile(controllerPath, controllerContent);
|
|
2936
|
+
console.log(colors11.green(`\u2705 Controller created: ${controllerPath}`));
|
|
2937
|
+
UFsModule.createFile(
|
|
2938
|
+
path8.join(paths.routesDir, `${featureName}.router.handler.ts`),
|
|
2939
|
+
generateLayeredRouterHandlerTemplate(featureName, methods)
|
|
2940
|
+
);
|
|
2941
|
+
console.log(colors11.green(`\u2705 Router Handler created: ${path8.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
|
|
2942
|
+
UFsModule.createFile(
|
|
2943
|
+
path8.join(paths.routesDir, `${featureName}.router.ts`),
|
|
2944
|
+
generateLayeredRouterTemplate(featureName)
|
|
2945
|
+
);
|
|
2946
|
+
await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
|
|
2947
|
+
console.log(colors11.green(`\u2705 Router created: ${path8.join(paths.routesDir, `${featureName}.router.ts`)}`));
|
|
2948
|
+
console.log(
|
|
2949
|
+
colors11.bgGreen(
|
|
2950
|
+
colors11.white(`
|
|
2951
|
+
\u{1F389} Feature "${featureName}" scaffolded with Layered architecture!
|
|
2952
|
+
`)
|
|
2953
|
+
)
|
|
2954
|
+
);
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2293
2957
|
// src/core/core.ts
|
|
2294
2958
|
(async () => {
|
|
2295
2959
|
UWelcomeMessage();
|
|
@@ -2298,18 +2962,40 @@ ${colors9.bgGreen(colors9.white(`
|
|
|
2298
2962
|
await customModuleScaffoldTemplate();
|
|
2299
2963
|
return;
|
|
2300
2964
|
}
|
|
2965
|
+
if (featureChoice === "mvc_architecture" || featureChoice === "layered_architecture") {
|
|
2966
|
+
const featureName2 = await _featureName();
|
|
2967
|
+
const directory2 = path9.join(process3.cwd(), "src", "features");
|
|
2968
|
+
const featureDirectory2 = path9.join(directory2, featureName2.toString());
|
|
2969
|
+
if (BaseService._isSubdirectoryExists(featureName2)) {
|
|
2970
|
+
BaseService._featureFounded(featureName2);
|
|
2971
|
+
}
|
|
2972
|
+
if (isCancel7(featureName2)) {
|
|
2973
|
+
BaseService._cancelOperation(featureDirectory2);
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
if (!fs5.existsSync(directory2)) {
|
|
2977
|
+
BaseService._checkFeatureDir();
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2980
|
+
if (featureChoice === "mvc_architecture") {
|
|
2981
|
+
await mvcModuleTemplate(featureName2.toString());
|
|
2982
|
+
} else {
|
|
2983
|
+
await layeredModuleTemplate(featureName2.toString());
|
|
2984
|
+
}
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2301
2987
|
if (!featureChoice || featureChoice !== "opticore_clean_module") {
|
|
2302
2988
|
process3.exit(0);
|
|
2303
2989
|
}
|
|
2304
2990
|
UCustomFeatureInfo(featureChoice);
|
|
2305
2991
|
const featureName = await _featureName();
|
|
2306
|
-
const directory =
|
|
2307
|
-
const featureDirectory =
|
|
2992
|
+
const directory = path9.join(process3.cwd(), "src", "features");
|
|
2993
|
+
const featureDirectory = path9.join(directory, featureName.toString());
|
|
2308
2994
|
const featureCleanModule = BaseService._isSubdirectoryExists(featureName);
|
|
2309
2995
|
if (featureCleanModule) {
|
|
2310
2996
|
BaseService._featureFounded(featureName);
|
|
2311
2997
|
}
|
|
2312
|
-
if (
|
|
2998
|
+
if (isCancel7(featureName)) {
|
|
2313
2999
|
BaseService._cancelOperation(featureDirectory);
|
|
2314
3000
|
} else {
|
|
2315
3001
|
try {
|