@manulz/nest-tools 1.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.
@@ -0,0 +1,569 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli/index.ts
27
+ var import_commander = require("commander");
28
+
29
+ // src/core/runner/command-runner.ts
30
+ var import_node_child_process = require("child_process");
31
+ var import_node_util = require("util");
32
+
33
+ // src/utils/logger.ts
34
+ var import_picocolors = __toESM(require("picocolors"));
35
+ var logger = {
36
+ info: (msg) => console.log(import_picocolors.default.cyan("\u2139 ") + msg),
37
+ success: (msg) => console.log(import_picocolors.default.green("\u2714 ") + import_picocolors.default.bold(msg)),
38
+ warn: (msg) => console.log(import_picocolors.default.yellow("\u26A0 ") + msg),
39
+ error: (msg) => console.error(import_picocolors.default.red("\u2716 ") + import_picocolors.default.bold(msg)),
40
+ step: (step, detail) => {
41
+ console.log(import_picocolors.default.blue("\u25B6 ") + import_picocolors.default.bold(step) + (detail ? import_picocolors.default.dim(` (${detail})`) : ""));
42
+ }
43
+ };
44
+
45
+ // src/core/runner/command-runner.ts
46
+ var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
47
+ async function runCommand(command, options = {}) {
48
+ const { cwd = process.cwd(), dryRun = false, silent = false } = options;
49
+ if (dryRun) {
50
+ logger.info(`[dry-run] Would execute: ${command}`);
51
+ return { stdout: "", stderr: "" };
52
+ }
53
+ if (!silent) {
54
+ logger.step(command);
55
+ }
56
+ try {
57
+ const result = await execAsync(command, { cwd });
58
+ return result;
59
+ } catch (error) {
60
+ const message = error.stderr || error.message || "Command failed";
61
+ throw new Error(`Failed to execute: "${command}"
62
+ ${message}`);
63
+ }
64
+ }
65
+
66
+ // src/core/config/index.ts
67
+ var import_promises = __toESM(require("fs/promises"));
68
+ var import_node_path = __toESM(require("path"));
69
+ var DEFAULT_CONFIG = {
70
+ spec: false,
71
+ flat: false,
72
+ architecture: "standard",
73
+ packageManager: "npm"
74
+ };
75
+ var CONFIG_FILENAMES = ["nest-tools.json", ".nesttoolsrc", ".nesttoolsrc.json"];
76
+ async function loadConfig(cwd = process.cwd()) {
77
+ for (const filename of CONFIG_FILENAMES) {
78
+ const configPath = import_node_path.default.join(cwd, filename);
79
+ try {
80
+ const data = await import_promises.default.readFile(configPath, "utf-8");
81
+ const parsed = JSON.parse(data);
82
+ return { ...DEFAULT_CONFIG, ...parsed };
83
+ } catch {
84
+ }
85
+ }
86
+ return DEFAULT_CONFIG;
87
+ }
88
+ async function createDefaultConfig(cwd = process.cwd()) {
89
+ const targetPath = import_node_path.default.join(cwd, "nest-tools.json");
90
+ const content = JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n";
91
+ await import_promises.default.writeFile(targetPath, content, "utf-8");
92
+ return targetPath;
93
+ }
94
+
95
+ // src/utils/strings.ts
96
+ function toKebabCase(str) {
97
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
98
+ }
99
+ function toPascalCase(str) {
100
+ return toKebabCase(str).split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
101
+ }
102
+ function toCamelCase(str) {
103
+ const pascal = toPascalCase(str);
104
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
105
+ }
106
+
107
+ // src/core/generator/generate-resource.ts
108
+ async function generateResource(options) {
109
+ const config = await loadConfig(options.cwd);
110
+ const rawName = options.name.trim();
111
+ const name = toKebabCase(rawName);
112
+ const spec = options.spec ?? config.spec ?? false;
113
+ const flat = options.flat ?? config.flat ?? false;
114
+ const dryRun = options.dryRun ?? false;
115
+ const cwd = options.cwd ?? process.cwd();
116
+ const specFlag = spec ? "" : "--no-spec";
117
+ const flatFlag = flat ? "--flat" : "";
118
+ const commands = [
119
+ `nest g mo ${name} ${flatFlag}`.trim(),
120
+ `nest g co ${name} ${specFlag} ${flatFlag}`.trim(),
121
+ `nest g s ${name} ${specFlag} ${flatFlag}`.trim()
122
+ ];
123
+ logger.info(`Generating resource "${name}" (spec: ${spec ? "yes" : "no"}, flat: ${flat ? "yes" : "no"})...`);
124
+ for (const cmd of commands) {
125
+ await runCommand(cmd, { cwd, dryRun });
126
+ }
127
+ logger.success(`Resource "${name}" generated successfully.`);
128
+ }
129
+
130
+ // src/core/generator/generate-clean-architecture.ts
131
+ var import_promises2 = __toESM(require("fs/promises"));
132
+ var import_node_path2 = __toESM(require("path"));
133
+ async function generateCleanArchitecture(options) {
134
+ const { dryRun = false, cwd = process.cwd() } = options;
135
+ const rawName = options.name.trim();
136
+ const kebab = toKebabCase(rawName);
137
+ const pascal = toPascalCase(rawName);
138
+ const camel = toCamelCase(rawName);
139
+ const baseDir = import_node_path2.default.join(cwd, "src", kebab);
140
+ const files = [
141
+ // 1. Domain Entity
142
+ {
143
+ filePath: import_node_path2.default.join(baseDir, "domain", "entities", `${kebab}.entity.ts`),
144
+ content: `export class ${pascal}Entity {
145
+ id!: string;
146
+ name!: string;
147
+ createdAt!: Date;
148
+ updatedAt!: Date;
149
+
150
+ constructor(partial: Partial<${pascal}Entity>) {
151
+ Object.assign(this, partial);
152
+ }
153
+ }
154
+ `
155
+ },
156
+ // 2. Domain Repository Interface & Token
157
+ {
158
+ filePath: import_node_path2.default.join(baseDir, "domain", "repositories", `${kebab}.repository.interface.ts`),
159
+ content: `import { ${pascal}Entity } from '../entities/${kebab}.entity';
160
+
161
+ export const ${pascal.toUpperCase()}_REPOSITORY = Symbol('${pascal.toUpperCase()}_REPOSITORY');
162
+
163
+ export interface ${pascal}Repository {
164
+ findById(id: string): Promise<${pascal}Entity | null>;
165
+ findAll(): Promise<${pascal}Entity[]>;
166
+ create(data: Partial<${pascal}Entity>): Promise<${pascal}Entity>;
167
+ delete(id: string): Promise<void>;
168
+ }
169
+ `
170
+ },
171
+ // 3. Application DTOs
172
+ {
173
+ filePath: import_node_path2.default.join(baseDir, "application", "dtos", `create-${kebab}.dto.ts`),
174
+ content: `export class Create${pascal}Dto {
175
+ name!: string;
176
+ }
177
+ `
178
+ },
179
+ {
180
+ filePath: import_node_path2.default.join(baseDir, "application", "dtos", `update-${kebab}.dto.ts`),
181
+ content: `export class Update${pascal}Dto {
182
+ name?: string;
183
+ }
184
+ `
185
+ },
186
+ // 4. Application Use Cases
187
+ {
188
+ filePath: import_node_path2.default.join(baseDir, "application", "use-cases", `create-${kebab}.use-case.ts`),
189
+ content: `import { Inject, Injectable } from '@nestjs/common';
190
+ import {
191
+ ${pascal}Repository,
192
+ ${pascal.toUpperCase()}_REPOSITORY,
193
+ } from '../../domain/repositories/${kebab}.repository.interface';
194
+ import { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';
195
+ import { Create${pascal}Dto } from '../dtos/create-${kebab}.dto';
196
+
197
+ @Injectable()
198
+ export class Create${pascal}UseCase {
199
+ constructor(
200
+ @Inject(${pascal.toUpperCase()}_REPOSITORY)
201
+ private readonly repository: ${pascal}Repository
202
+ ) {}
203
+
204
+ async execute(dto: Create${pascal}Dto): Promise<${pascal}Entity> {
205
+ return this.repository.create({
206
+ name: dto.name,
207
+ createdAt: new Date(),
208
+ updatedAt: new Date(),
209
+ });
210
+ }
211
+ }
212
+ `
213
+ },
214
+ {
215
+ filePath: import_node_path2.default.join(baseDir, "application", "use-cases", `find-${kebab}.use-case.ts`),
216
+ content: `import { Inject, Injectable, NotFoundException } from '@nestjs/common';
217
+ import {
218
+ ${pascal}Repository,
219
+ ${pascal.toUpperCase()}_REPOSITORY,
220
+ } from '../../domain/repositories/${kebab}.repository.interface';
221
+ import { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';
222
+
223
+ @Injectable()
224
+ export class Find${pascal}UseCase {
225
+ constructor(
226
+ @Inject(${pascal.toUpperCase()}_REPOSITORY)
227
+ private readonly repository: ${pascal}Repository
228
+ ) {}
229
+
230
+ async execute(id: string): Promise<${pascal}Entity> {
231
+ const item = await this.repository.findById(id);
232
+ if (!item) {
233
+ throw new NotFoundException(\`${pascal} with id "\${id}" not found\`);
234
+ }
235
+ return item;
236
+ }
237
+ }
238
+ `
239
+ },
240
+ // 5. Infrastructure In-Memory Repository
241
+ {
242
+ filePath: import_node_path2.default.join(
243
+ baseDir,
244
+ "infrastructure",
245
+ "repositories",
246
+ `in-memory-${kebab}.repository.ts`
247
+ ),
248
+ content: `import { Injectable } from '@nestjs/common';
249
+ import {
250
+ ${pascal}Repository,
251
+ } from '../../domain/repositories/${kebab}.repository.interface';
252
+ import { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';
253
+
254
+ @Injectable()
255
+ export class InMemory${pascal}Repository implements ${pascal}Repository {
256
+ private readonly items: Map<string, ${pascal}Entity> = new Map();
257
+
258
+ async findById(id: string): Promise<${pascal}Entity | null> {
259
+ return this.items.get(id) || null;
260
+ }
261
+
262
+ async findAll(): Promise<${pascal}Entity[]> {
263
+ return Array.from(this.items.values());
264
+ }
265
+
266
+ async create(data: Partial<${pascal}Entity>): Promise<${pascal}Entity> {
267
+ const id = (this.items.size + 1).toString();
268
+ const entity = new ${pascal}Entity({
269
+ id,
270
+ name: data.name ?? 'Untitled',
271
+ createdAt: data.createdAt ?? new Date(),
272
+ updatedAt: data.updatedAt ?? new Date(),
273
+ });
274
+ this.items.set(id, entity);
275
+ return entity;
276
+ }
277
+
278
+ async delete(id: string): Promise<void> {
279
+ this.items.delete(id);
280
+ }
281
+ }
282
+ `
283
+ },
284
+ // 6. Infrastructure Controller
285
+ {
286
+ filePath: import_node_path2.default.join(baseDir, "infrastructure", "controllers", `${kebab}.controller.ts`),
287
+ content: `import { Body, Controller, Get, Param, Post } from '@nestjs/common';
288
+ import { Create${pascal}UseCase } from '../../application/use-cases/create-${kebab}.use-case';
289
+ import { Find${pascal}UseCase } from '../../application/use-cases/find-${kebab}.use-case';
290
+ import { Create${pascal}Dto } from '../../application/dtos/create-${kebab}.dto';
291
+
292
+ @Controller('${kebab}')
293
+ export class ${pascal}Controller {
294
+ constructor(
295
+ private readonly createUseCase: Create${pascal}UseCase,
296
+ private readonly findUseCase: Find${pascal}UseCase
297
+ ) {}
298
+
299
+ @Post()
300
+ create(@Body() dto: Create${pascal}Dto) {
301
+ return this.createUseCase.execute(dto);
302
+ }
303
+
304
+ @Get(':id')
305
+ findOne(@Param('id') id: string) {
306
+ return this.findUseCase.execute(id);
307
+ }
308
+ }
309
+ `
310
+ },
311
+ // 7. NestJS Module
312
+ {
313
+ filePath: import_node_path2.default.join(baseDir, `${kebab}.module.ts`),
314
+ content: `import { Module } from '@nestjs/common';
315
+ import { ${pascal}Controller } from './infrastructure/controllers/${kebab}.controller';
316
+ import { Create${pascal}UseCase } from './application/use-cases/create-${kebab}.use-case';
317
+ import { Find${pascal}UseCase } from './application/use-cases/find-${kebab}.use-case';
318
+ import { ${pascal.toUpperCase()}_REPOSITORY } from './domain/repositories/${kebab}.repository.interface';
319
+ import { InMemory${pascal}Repository } from './infrastructure/repositories/in-memory-${kebab}.repository';
320
+
321
+ @Module({
322
+ controllers: [${pascal}Controller],
323
+ providers: [
324
+ Create${pascal}UseCase,
325
+ Find${pascal}UseCase,
326
+ {
327
+ provide: ${pascal.toUpperCase()}_REPOSITORY,
328
+ useClass: InMemory${pascal}Repository,
329
+ },
330
+ ],
331
+ exports: [Create${pascal}UseCase, Find${pascal}UseCase, ${pascal.toUpperCase()}_REPOSITORY],
332
+ })
333
+ export class ${pascal}Module {}
334
+ `
335
+ }
336
+ ];
337
+ logger.info(`Generating Clean Architecture module for "${kebab}" at ${baseDir}...`);
338
+ for (const file of files) {
339
+ if (dryRun) {
340
+ logger.info(`[dry-run] Would create: ${import_node_path2.default.relative(cwd, file.filePath)}`);
341
+ } else {
342
+ await import_promises2.default.mkdir(import_node_path2.default.dirname(file.filePath), { recursive: true });
343
+ await import_promises2.default.writeFile(file.filePath, file.content, "utf-8");
344
+ logger.step(`Created ${import_node_path2.default.relative(cwd, file.filePath)}`);
345
+ }
346
+ }
347
+ logger.success(`Clean Architecture structure for "${pascal}Module" generated!`);
348
+ logger.info(`Remember to import ${pascal}Module in your AppModule.`);
349
+ }
350
+
351
+ // src/core/diagnostics/doctor.ts
352
+ var import_promises3 = __toESM(require("fs/promises"));
353
+ var import_node_path3 = __toESM(require("path"));
354
+ var import_picocolors2 = __toESM(require("picocolors"));
355
+ async function runDoctor(cwd = process.cwd()) {
356
+ const report = {
357
+ isNestProject: false,
358
+ issues: [],
359
+ recommendations: []
360
+ };
361
+ logger.info("Running nest-tools doctor diagnostics...\n");
362
+ const pkgPath = import_node_path3.default.join(cwd, "package.json");
363
+ let pkg = null;
364
+ try {
365
+ const pkgRaw = await import_promises3.default.readFile(pkgPath, "utf-8");
366
+ pkg = JSON.parse(pkgRaw);
367
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
368
+ if (deps["@nestjs/core"] || deps["@nestjs/common"]) {
369
+ report.isNestProject = true;
370
+ console.log(import_picocolors2.default.green("\u2714") + " NestJS dependencies detected in package.json");
371
+ } else {
372
+ report.issues.push("Could not find @nestjs/core or @nestjs/common in package.json.");
373
+ }
374
+ } catch {
375
+ report.issues.push("No package.json found in current working directory.");
376
+ }
377
+ try {
378
+ await import_promises3.default.access(import_node_path3.default.join(cwd, "nest-cli.json"));
379
+ console.log(import_picocolors2.default.green("\u2714") + " nest-cli.json configuration found");
380
+ } catch {
381
+ report.recommendations.push('nest-cli.json is missing. Consider generating one with "nest new".');
382
+ }
383
+ try {
384
+ await import_promises3.default.access(import_node_path3.default.join(cwd, "tsconfig.json"));
385
+ console.log(import_picocolors2.default.green("\u2714") + " tsconfig.json found");
386
+ } catch {
387
+ report.issues.push("tsconfig.json is missing in project root.");
388
+ }
389
+ try {
390
+ await import_promises3.default.access(import_node_path3.default.join(cwd, ".env"));
391
+ try {
392
+ await import_promises3.default.access(import_node_path3.default.join(cwd, ".env.example"));
393
+ console.log(import_picocolors2.default.green("\u2714") + " .env and .env.example are present");
394
+ } catch {
395
+ report.recommendations.push(
396
+ ".env exists but .env.example is missing. It is recommended to commit an example file."
397
+ );
398
+ }
399
+ } catch {
400
+ }
401
+ try {
402
+ const appModulePath = import_node_path3.default.join(cwd, "src", "app.module.ts");
403
+ const appModuleContent = await import_promises3.default.readFile(appModulePath, "utf-8");
404
+ const srcDir = import_node_path3.default.join(cwd, "src");
405
+ const entries = await import_promises3.default.readdir(srcDir, { withFileTypes: true });
406
+ for (const entry of entries) {
407
+ if (entry.isDirectory()) {
408
+ const potentialModule = `${entry.name}.module.ts`;
409
+ const moduleFilePath = import_node_path3.default.join(srcDir, entry.name, potentialModule);
410
+ try {
411
+ await import_promises3.default.access(moduleFilePath);
412
+ if (!appModuleContent.includes(potentialModule.replace(".ts", "")) && !appModuleContent.includes(entry.name)) {
413
+ report.recommendations.push(
414
+ `Module "${entry.name}" was found at src/${entry.name}/${potentialModule}, but might not be imported in app.module.ts.`
415
+ );
416
+ }
417
+ } catch {
418
+ }
419
+ }
420
+ }
421
+ } catch {
422
+ }
423
+ console.log("");
424
+ if (report.issues.length > 0) {
425
+ logger.error(`Found ${report.issues.length} issue(s):`);
426
+ for (const issue of report.issues) {
427
+ console.log(import_picocolors2.default.red(" \u2716 ") + issue);
428
+ }
429
+ } else {
430
+ logger.success("No critical issues found!");
431
+ }
432
+ if (report.recommendations.length > 0) {
433
+ logger.warn(`Found ${report.recommendations.length} recommendation(s):`);
434
+ for (const rec of report.recommendations) {
435
+ console.log(import_picocolors2.default.yellow(" \u279C ") + rec);
436
+ }
437
+ }
438
+ return report;
439
+ }
440
+
441
+ // src/cli/prompts.ts
442
+ var p = __toESM(require("@clack/prompts"));
443
+ var import_picocolors3 = __toESM(require("picocolors"));
444
+ async function runInteractive() {
445
+ p.intro(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" @manulz/nest-tools ")));
446
+ const action = await p.select({
447
+ message: "What would you like to do?",
448
+ options: [
449
+ { value: "resource", label: "Generate Standard Resource (Module + Controller + Service)" },
450
+ { value: "clean", label: "Generate Clean Architecture / Hexagonal Module" },
451
+ { value: "init", label: "Initialize nest-tools.json config file" },
452
+ { value: "doctor", label: "Run project diagnostics (Doctor)" }
453
+ ]
454
+ });
455
+ if (p.isCancel(action)) {
456
+ p.cancel("Operation cancelled.");
457
+ process.exit(0);
458
+ }
459
+ if (action === "doctor") {
460
+ await runDoctor();
461
+ p.outro(import_picocolors3.default.green("Diagnostics completed!"));
462
+ return;
463
+ }
464
+ if (action === "init") {
465
+ const configPath = await createDefaultConfig();
466
+ p.outro(import_picocolors3.default.green(`Created config at: ${configPath}`));
467
+ return;
468
+ }
469
+ const name = await p.text({
470
+ message: "What is the name of the resource/module?",
471
+ placeholder: "e.g. users, products, auth",
472
+ validate: (value) => {
473
+ if (!value || value.trim().length === 0) {
474
+ return "Please enter a valid name";
475
+ }
476
+ }
477
+ });
478
+ if (p.isCancel(name)) {
479
+ p.cancel("Operation cancelled.");
480
+ process.exit(0);
481
+ }
482
+ if (action === "resource") {
483
+ const spec = await p.confirm({
484
+ message: "Do you want to generate spec/test files?",
485
+ initialValue: false
486
+ });
487
+ if (p.isCancel(spec)) {
488
+ p.cancel("Operation cancelled.");
489
+ process.exit(0);
490
+ }
491
+ const s = p.spinner();
492
+ s.start(`Generating resource "${name}"...`);
493
+ try {
494
+ await generateResource({ name, spec: Boolean(spec) });
495
+ s.stop(`Resource "${name}" generated!`);
496
+ p.outro(import_picocolors3.default.green("Done!"));
497
+ } catch (err) {
498
+ s.stop(import_picocolors3.default.red("Generation failed."));
499
+ p.cancel(err.message);
500
+ process.exit(1);
501
+ }
502
+ } else if (action === "clean") {
503
+ const s = p.spinner();
504
+ s.start(`Generating Clean Architecture module "${name}"...`);
505
+ try {
506
+ await generateCleanArchitecture({ name });
507
+ s.stop(`Clean Architecture module "${name}" generated!`);
508
+ p.outro(import_picocolors3.default.green("Done!"));
509
+ } catch (err) {
510
+ s.stop(import_picocolors3.default.red("Generation failed."));
511
+ p.cancel(err.message);
512
+ process.exit(1);
513
+ }
514
+ }
515
+ }
516
+
517
+ // src/cli/index.ts
518
+ var program = new import_commander.Command();
519
+ program.name("nest-tools").description("Developer utilities, clean architecture generator, and runtime helpers for NestJS").version("1.1.0");
520
+ program.command("generate <name>").alias("g").description("Generate Module, Controller, and Service for a resource").option("--spec", "Include unit test files (.spec.ts)").option("--no-spec", "Exclude unit test files (.spec.ts)").option("--flat", "Generate elements without creating a subfolder").option("--dry-run", "Preview the commands without executing them").action(async (name, options) => {
521
+ try {
522
+ await generateResource({
523
+ name,
524
+ spec: options.spec,
525
+ flat: options.flat,
526
+ dryRun: options.dryRun
527
+ });
528
+ } catch (error) {
529
+ logger.error(error.message);
530
+ process.exit(1);
531
+ }
532
+ });
533
+ program.command("hex <name>").alias("clean").description("Generate a Clean Architecture / Hexagonal module structure").option("--dry-run", "Preview the files to create without writing them").action(async (name, options) => {
534
+ try {
535
+ await generateCleanArchitecture({
536
+ name,
537
+ dryRun: options.dryRun
538
+ });
539
+ } catch (error) {
540
+ logger.error(error.message);
541
+ process.exit(1);
542
+ }
543
+ });
544
+ program.command("doctor").description("Inspect current NestJS project health and check for common issues").action(async () => {
545
+ try {
546
+ await runDoctor();
547
+ } catch (error) {
548
+ logger.error(error.message);
549
+ process.exit(1);
550
+ }
551
+ });
552
+ program.command("init").description("Create default nest-tools.json configuration file").action(async () => {
553
+ try {
554
+ const configPath = await createDefaultConfig();
555
+ logger.success(`Configuration file created at: ${configPath}`);
556
+ } catch (error) {
557
+ logger.error(error.message);
558
+ process.exit(1);
559
+ }
560
+ });
561
+ if (process.argv.slice(2).length === 0) {
562
+ runInteractive().catch((error) => {
563
+ logger.error(error.message);
564
+ process.exit(1);
565
+ });
566
+ } else {
567
+ program.parse(process.argv);
568
+ }
569
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/core/runner/command-runner.ts","../../src/utils/logger.ts","../../src/core/config/index.ts","../../src/utils/strings.ts","../../src/core/generator/generate-resource.ts","../../src/core/generator/generate-clean-architecture.ts","../../src/core/diagnostics/doctor.ts","../../src/cli/prompts.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { generateResource } from '../core/generator/generate-resource';\nimport { generateCleanArchitecture } from '../core/generator/generate-clean-architecture';\nimport { runDoctor } from '../core/diagnostics/doctor';\nimport { createDefaultConfig } from '../core/config';\nimport { runInteractive } from './prompts';\nimport { logger } from '../utils/logger';\n\nconst program = new Command();\n\nprogram\n .name('nest-tools')\n .description('Developer utilities, clean architecture generator, and runtime helpers for NestJS')\n .version('1.1.0');\n\n// Subcommand: generate (g)\nprogram\n .command('generate <name>')\n .alias('g')\n .description('Generate Module, Controller, and Service for a resource')\n .option('--spec', 'Include unit test files (.spec.ts)')\n .option('--no-spec', 'Exclude unit test files (.spec.ts)')\n .option('--flat', 'Generate elements without creating a subfolder')\n .option('--dry-run', 'Preview the commands without executing them')\n .action(async (name: string, options: { spec?: boolean; flat?: boolean; dryRun?: boolean }) => {\n try {\n await generateResource({\n name,\n spec: options.spec,\n flat: options.flat,\n dryRun: options.dryRun,\n });\n } catch (error: any) {\n logger.error(error.message);\n process.exit(1);\n }\n });\n\n// Subcommand: hex / clean\nprogram\n .command('hex <name>')\n .alias('clean')\n .description('Generate a Clean Architecture / Hexagonal module structure')\n .option('--dry-run', 'Preview the files to create without writing them')\n .action(async (name: string, options: { dryRun?: boolean }) => {\n try {\n await generateCleanArchitecture({\n name,\n dryRun: options.dryRun,\n });\n } catch (error: any) {\n logger.error(error.message);\n process.exit(1);\n }\n });\n\n// Subcommand: doctor\nprogram\n .command('doctor')\n .description('Inspect current NestJS project health and check for common issues')\n .action(async () => {\n try {\n await runDoctor();\n } catch (error: any) {\n logger.error(error.message);\n process.exit(1);\n }\n });\n\n// Subcommand: init\nprogram\n .command('init')\n .description('Create default nest-tools.json configuration file')\n .action(async () => {\n try {\n const configPath = await createDefaultConfig();\n logger.success(`Configuration file created at: ${configPath}`);\n } catch (error: any) {\n logger.error(error.message);\n process.exit(1);\n }\n });\n\n// If no arguments provided, launch interactive prompt\nif (process.argv.slice(2).length === 0) {\n runInteractive().catch((error) => {\n logger.error(error.message);\n process.exit(1);\n });\n} else {\n program.parse(process.argv);\n}\n","import { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { logger } from '../../utils/logger';\n\nconst execAsync = promisify(exec);\n\nexport interface RunCommandOptions {\n cwd?: string;\n dryRun?: boolean;\n silent?: boolean;\n}\n\nexport async function runCommand(\n command: string,\n options: RunCommandOptions = {}\n): Promise<{ stdout: string; stderr: string }> {\n const { cwd = process.cwd(), dryRun = false, silent = false } = options;\n\n if (dryRun) {\n logger.info(`[dry-run] Would execute: ${command}`);\n return { stdout: '', stderr: '' };\n }\n\n if (!silent) {\n logger.step(command);\n }\n\n try {\n const result = await execAsync(command, { cwd });\n return result;\n } catch (error: any) {\n const message = error.stderr || error.message || 'Command failed';\n throw new Error(`Failed to execute: \"${command}\"\\n${message}`);\n }\n}\n","import pc from 'picocolors';\n\nexport const logger = {\n info: (msg: string) => console.log(pc.cyan('ℹ ') + msg),\n success: (msg: string) => console.log(pc.green('✔ ') + pc.bold(msg)),\n warn: (msg: string) => console.log(pc.yellow('⚠ ') + msg),\n error: (msg: string) => console.error(pc.red('✖ ') + pc.bold(msg)),\n step: (step: string, detail?: string) => {\n console.log(pc.blue('▶ ') + pc.bold(step) + (detail ? pc.dim(` (${detail})`) : ''));\n },\n};\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport interface NestToolsConfig {\n spec?: boolean;\n flat?: boolean;\n architecture?: 'standard' | 'clean';\n packageManager?: 'npm' | 'yarn' | 'pnpm';\n}\n\nexport const DEFAULT_CONFIG: NestToolsConfig = {\n spec: false,\n flat: false,\n architecture: 'standard',\n packageManager: 'npm',\n};\n\nconst CONFIG_FILENAMES = ['nest-tools.json', '.nesttoolsrc', '.nesttoolsrc.json'];\n\nexport async function loadConfig(cwd = process.cwd()): Promise<NestToolsConfig> {\n for (const filename of CONFIG_FILENAMES) {\n const configPath = path.join(cwd, filename);\n try {\n const data = await fs.readFile(configPath, 'utf-8');\n const parsed = JSON.parse(data);\n return { ...DEFAULT_CONFIG, ...parsed };\n } catch {\n // Continue searching\n }\n }\n\n return DEFAULT_CONFIG;\n}\n\nexport async function createDefaultConfig(cwd = process.cwd()): Promise<string> {\n const targetPath = path.join(cwd, 'nest-tools.json');\n const content = JSON.stringify(DEFAULT_CONFIG, null, 2) + '\\n';\n await fs.writeFile(targetPath, content, 'utf-8');\n return targetPath;\n}\n","export function toKebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\nexport function toPascalCase(str: string): string {\n return toKebabCase(str)\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\nexport function toCamelCase(str: string): string {\n const pascal = toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n","import { runCommand } from '../runner/command-runner';\nimport { loadConfig } from '../config';\nimport { logger } from '../../utils/logger';\nimport { toKebabCase } from '../../utils/strings';\n\nexport interface GenerateResourceOptions {\n name: string;\n spec?: boolean;\n flat?: boolean;\n dryRun?: boolean;\n cwd?: string;\n}\n\nexport async function generateResource(options: GenerateResourceOptions): Promise<void> {\n const config = await loadConfig(options.cwd);\n const rawName = options.name.trim();\n const name = toKebabCase(rawName);\n\n const spec = options.spec ?? config.spec ?? false;\n const flat = options.flat ?? config.flat ?? false;\n const dryRun = options.dryRun ?? false;\n const cwd = options.cwd ?? process.cwd();\n\n const specFlag = spec ? '' : '--no-spec';\n const flatFlag = flat ? '--flat' : '';\n\n const commands = [\n `nest g mo ${name} ${flatFlag}`.trim(),\n `nest g co ${name} ${specFlag} ${flatFlag}`.trim(),\n `nest g s ${name} ${specFlag} ${flatFlag}`.trim(),\n ];\n\n logger.info(`Generating resource \"${name}\" (spec: ${spec ? 'yes' : 'no'}, flat: ${flat ? 'yes' : 'no'})...`);\n\n for (const cmd of commands) {\n await runCommand(cmd, { cwd, dryRun });\n }\n\n logger.success(`Resource \"${name}\" generated successfully.`);\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { logger } from '../../utils/logger';\nimport { toCamelCase, toKebabCase, toPascalCase } from '../../utils/strings';\n\nexport interface GenerateCleanArchitectureOptions {\n name: string;\n dryRun?: boolean;\n cwd?: string;\n}\n\nexport async function generateCleanArchitecture(\n options: GenerateCleanArchitectureOptions\n): Promise<void> {\n const { dryRun = false, cwd = process.cwd() } = options;\n const rawName = options.name.trim();\n const kebab = toKebabCase(rawName);\n const pascal = toPascalCase(rawName);\n const camel = toCamelCase(rawName);\n\n const baseDir = path.join(cwd, 'src', kebab);\n\n const files: { filePath: string; content: string }[] = [\n // 1. Domain Entity\n {\n filePath: path.join(baseDir, 'domain', 'entities', `${kebab}.entity.ts`),\n content: `export class ${pascal}Entity {\n id!: string;\n name!: string;\n createdAt!: Date;\n updatedAt!: Date;\n\n constructor(partial: Partial<${pascal}Entity>) {\n Object.assign(this, partial);\n }\n}\n`,\n },\n // 2. Domain Repository Interface & Token\n {\n filePath: path.join(baseDir, 'domain', 'repositories', `${kebab}.repository.interface.ts`),\n content: `import { ${pascal}Entity } from '../entities/${kebab}.entity';\n\nexport const ${pascal.toUpperCase()}_REPOSITORY = Symbol('${pascal.toUpperCase()}_REPOSITORY');\n\nexport interface ${pascal}Repository {\n findById(id: string): Promise<${pascal}Entity | null>;\n findAll(): Promise<${pascal}Entity[]>;\n create(data: Partial<${pascal}Entity>): Promise<${pascal}Entity>;\n delete(id: string): Promise<void>;\n}\n`,\n },\n // 3. Application DTOs\n {\n filePath: path.join(baseDir, 'application', 'dtos', `create-${kebab}.dto.ts`),\n content: `export class Create${pascal}Dto {\n name!: string;\n}\n`,\n },\n {\n filePath: path.join(baseDir, 'application', 'dtos', `update-${kebab}.dto.ts`),\n content: `export class Update${pascal}Dto {\n name?: string;\n}\n`,\n },\n // 4. Application Use Cases\n {\n filePath: path.join(baseDir, 'application', 'use-cases', `create-${kebab}.use-case.ts`),\n content: `import { Inject, Injectable } from '@nestjs/common';\nimport {\n ${pascal}Repository,\n ${pascal.toUpperCase()}_REPOSITORY,\n} from '../../domain/repositories/${kebab}.repository.interface';\nimport { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';\nimport { Create${pascal}Dto } from '../dtos/create-${kebab}.dto';\n\n@Injectable()\nexport class Create${pascal}UseCase {\n constructor(\n @Inject(${pascal.toUpperCase()}_REPOSITORY)\n private readonly repository: ${pascal}Repository\n ) {}\n\n async execute(dto: Create${pascal}Dto): Promise<${pascal}Entity> {\n return this.repository.create({\n name: dto.name,\n createdAt: new Date(),\n updatedAt: new Date(),\n });\n }\n}\n`,\n },\n {\n filePath: path.join(baseDir, 'application', 'use-cases', `find-${kebab}.use-case.ts`),\n content: `import { Inject, Injectable, NotFoundException } from '@nestjs/common';\nimport {\n ${pascal}Repository,\n ${pascal.toUpperCase()}_REPOSITORY,\n} from '../../domain/repositories/${kebab}.repository.interface';\nimport { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';\n\n@Injectable()\nexport class Find${pascal}UseCase {\n constructor(\n @Inject(${pascal.toUpperCase()}_REPOSITORY)\n private readonly repository: ${pascal}Repository\n ) {}\n\n async execute(id: string): Promise<${pascal}Entity> {\n const item = await this.repository.findById(id);\n if (!item) {\n throw new NotFoundException(\\`${pascal} with id \"\\${id}\" not found\\`);\n }\n return item;\n }\n}\n`,\n },\n // 5. Infrastructure In-Memory Repository\n {\n filePath: path.join(\n baseDir,\n 'infrastructure',\n 'repositories',\n `in-memory-${kebab}.repository.ts`\n ),\n content: `import { Injectable } from '@nestjs/common';\nimport {\n ${pascal}Repository,\n} from '../../domain/repositories/${kebab}.repository.interface';\nimport { ${pascal}Entity } from '../../domain/entities/${kebab}.entity';\n\n@Injectable()\nexport class InMemory${pascal}Repository implements ${pascal}Repository {\n private readonly items: Map<string, ${pascal}Entity> = new Map();\n\n async findById(id: string): Promise<${pascal}Entity | null> {\n return this.items.get(id) || null;\n }\n\n async findAll(): Promise<${pascal}Entity[]> {\n return Array.from(this.items.values());\n }\n\n async create(data: Partial<${pascal}Entity>): Promise<${pascal}Entity> {\n const id = (this.items.size + 1).toString();\n const entity = new ${pascal}Entity({\n id,\n name: data.name ?? 'Untitled',\n createdAt: data.createdAt ?? new Date(),\n updatedAt: data.updatedAt ?? new Date(),\n });\n this.items.set(id, entity);\n return entity;\n }\n\n async delete(id: string): Promise<void> {\n this.items.delete(id);\n }\n}\n`,\n },\n // 6. Infrastructure Controller\n {\n filePath: path.join(baseDir, 'infrastructure', 'controllers', `${kebab}.controller.ts`),\n content: `import { Body, Controller, Get, Param, Post } from '@nestjs/common';\nimport { Create${pascal}UseCase } from '../../application/use-cases/create-${kebab}.use-case';\nimport { Find${pascal}UseCase } from '../../application/use-cases/find-${kebab}.use-case';\nimport { Create${pascal}Dto } from '../../application/dtos/create-${kebab}.dto';\n\n@Controller('${kebab}')\nexport class ${pascal}Controller {\n constructor(\n private readonly createUseCase: Create${pascal}UseCase,\n private readonly findUseCase: Find${pascal}UseCase\n ) {}\n\n @Post()\n create(@Body() dto: Create${pascal}Dto) {\n return this.createUseCase.execute(dto);\n }\n\n @Get(':id')\n findOne(@Param('id') id: string) {\n return this.findUseCase.execute(id);\n }\n}\n`,\n },\n // 7. NestJS Module\n {\n filePath: path.join(baseDir, `${kebab}.module.ts`),\n content: `import { Module } from '@nestjs/common';\nimport { ${pascal}Controller } from './infrastructure/controllers/${kebab}.controller';\nimport { Create${pascal}UseCase } from './application/use-cases/create-${kebab}.use-case';\nimport { Find${pascal}UseCase } from './application/use-cases/find-${kebab}.use-case';\nimport { ${pascal.toUpperCase()}_REPOSITORY } from './domain/repositories/${kebab}.repository.interface';\nimport { InMemory${pascal}Repository } from './infrastructure/repositories/in-memory-${kebab}.repository';\n\n@Module({\n controllers: [${pascal}Controller],\n providers: [\n Create${pascal}UseCase,\n Find${pascal}UseCase,\n {\n provide: ${pascal.toUpperCase()}_REPOSITORY,\n useClass: InMemory${pascal}Repository,\n },\n ],\n exports: [Create${pascal}UseCase, Find${pascal}UseCase, ${pascal.toUpperCase()}_REPOSITORY],\n})\nexport class ${pascal}Module {}\n`,\n },\n ];\n\n logger.info(`Generating Clean Architecture module for \"${kebab}\" at ${baseDir}...`);\n\n for (const file of files) {\n if (dryRun) {\n logger.info(`[dry-run] Would create: ${path.relative(cwd, file.filePath)}`);\n } else {\n await fs.mkdir(path.dirname(file.filePath), { recursive: true });\n await fs.writeFile(file.filePath, file.content, 'utf-8');\n logger.step(`Created ${path.relative(cwd, file.filePath)}`);\n }\n }\n\n logger.success(`Clean Architecture structure for \"${pascal}Module\" generated!`);\n logger.info(`Remember to import ${pascal}Module in your AppModule.`);\n}\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport pc from 'picocolors';\nimport { logger } from '../../utils/logger';\n\nexport interface DoctorReport {\n isNestProject: boolean;\n issues: string[];\n recommendations: string[];\n}\n\nexport async function runDoctor(cwd = process.cwd()): Promise<DoctorReport> {\n const report: DoctorReport = {\n isNestProject: false,\n issues: [],\n recommendations: [],\n };\n\n logger.info('Running nest-tools doctor diagnostics...\\n');\n\n // 1. Check package.json\n const pkgPath = path.join(cwd, 'package.json');\n let pkg: any = null;\n try {\n const pkgRaw = await fs.readFile(pkgPath, 'utf-8');\n pkg = JSON.parse(pkgRaw);\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n if (deps['@nestjs/core'] || deps['@nestjs/common']) {\n report.isNestProject = true;\n console.log(pc.green('✔') + ' NestJS dependencies detected in package.json');\n } else {\n report.issues.push('Could not find @nestjs/core or @nestjs/common in package.json.');\n }\n } catch {\n report.issues.push('No package.json found in current working directory.');\n }\n\n // 2. Check nest-cli.json\n try {\n await fs.access(path.join(cwd, 'nest-cli.json'));\n console.log(pc.green('✔') + ' nest-cli.json configuration found');\n } catch {\n report.recommendations.push('nest-cli.json is missing. Consider generating one with \"nest new\".');\n }\n\n // 3. Check tsconfig.json\n try {\n await fs.access(path.join(cwd, 'tsconfig.json'));\n console.log(pc.green('✔') + ' tsconfig.json found');\n } catch {\n report.issues.push('tsconfig.json is missing in project root.');\n }\n\n // 4. Check .env and .env.example\n try {\n await fs.access(path.join(cwd, '.env'));\n try {\n await fs.access(path.join(cwd, '.env.example'));\n console.log(pc.green('✔') + ' .env and .env.example are present');\n } catch {\n report.recommendations.push(\n '.env exists but .env.example is missing. It is recommended to commit an example file.'\n );\n }\n } catch {\n // No .env, ignore\n }\n\n // 5. Module check (look for orphan modules)\n try {\n const appModulePath = path.join(cwd, 'src', 'app.module.ts');\n const appModuleContent = await fs.readFile(appModulePath, 'utf-8');\n\n const srcDir = path.join(cwd, 'src');\n const entries = await fs.readdir(srcDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const potentialModule = `${entry.name}.module.ts`;\n const moduleFilePath = path.join(srcDir, entry.name, potentialModule);\n try {\n await fs.access(moduleFilePath);\n if (!appModuleContent.includes(potentialModule.replace('.ts', '')) &&\n !appModuleContent.includes(entry.name)) {\n report.recommendations.push(\n `Module \"${entry.name}\" was found at src/${entry.name}/${potentialModule}, but might not be imported in app.module.ts.`\n );\n }\n } catch {\n // not a module dir\n }\n }\n }\n } catch {\n // app.module.ts doesn't exist or isn't accessible\n }\n\n console.log('');\n if (report.issues.length > 0) {\n logger.error(`Found ${report.issues.length} issue(s):`);\n for (const issue of report.issues) {\n console.log(pc.red(' ✖ ') + issue);\n }\n } else {\n logger.success('No critical issues found!');\n }\n\n if (report.recommendations.length > 0) {\n logger.warn(`Found ${report.recommendations.length} recommendation(s):`);\n for (const rec of report.recommendations) {\n console.log(pc.yellow(' ➜ ') + rec);\n }\n }\n\n return report;\n}\n","import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { generateResource } from '../core/generator/generate-resource';\nimport { generateCleanArchitecture } from '../core/generator/generate-clean-architecture';\nimport { runDoctor } from '../core/diagnostics/doctor';\nimport { createDefaultConfig } from '../core/config';\n\nexport async function runInteractive(): Promise<void> {\n p.intro(pc.bgCyan(pc.black(' @manulz/nest-tools ')));\n\n const action = await p.select({\n message: 'What would you like to do?',\n options: [\n { value: 'resource', label: 'Generate Standard Resource (Module + Controller + Service)' },\n { value: 'clean', label: 'Generate Clean Architecture / Hexagonal Module' },\n { value: 'init', label: 'Initialize nest-tools.json config file' },\n { value: 'doctor', label: 'Run project diagnostics (Doctor)' },\n ],\n });\n\n if (p.isCancel(action)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n if (action === 'doctor') {\n await runDoctor();\n p.outro(pc.green('Diagnostics completed!'));\n return;\n }\n\n if (action === 'init') {\n const configPath = await createDefaultConfig();\n p.outro(pc.green(`Created config at: ${configPath}`));\n return;\n }\n\n const name = await p.text({\n message: 'What is the name of the resource/module?',\n placeholder: 'e.g. users, products, auth',\n validate: (value) => {\n if (!value || value.trim().length === 0) {\n return 'Please enter a valid name';\n }\n },\n });\n\n if (p.isCancel(name)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n if (action === 'resource') {\n const spec = await p.confirm({\n message: 'Do you want to generate spec/test files?',\n initialValue: false,\n });\n\n if (p.isCancel(spec)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n const s = p.spinner();\n s.start(`Generating resource \"${name}\"...`);\n try {\n await generateResource({ name: name as string, spec: Boolean(spec) });\n s.stop(`Resource \"${name}\" generated!`);\n p.outro(pc.green('Done!'));\n } catch (err: any) {\n s.stop(pc.red('Generation failed.'));\n p.cancel(err.message);\n process.exit(1);\n }\n } else if (action === 'clean') {\n const s = p.spinner();\n s.start(`Generating Clean Architecture module \"${name}\"...`);\n try {\n await generateCleanArchitecture({ name: name as string });\n s.stop(`Clean Architecture module \"${name}\" generated!`);\n p.outro(pc.green('Done!'));\n } catch (err: any) {\n s.stop(pc.red('Generation failed.'));\n p.cancel(err.message);\n process.exit(1);\n }\n }\n}\n"],"mappings":"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","names":["pc","path","fs","import_promises","import_node_path","path","fs","import_promises","import_node_path","import_picocolors","path","fs","pc","import_picocolors","pc"]}