simpledi-app-generator 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -34
- package/dist/cli.js +27 -2
- package/dist/cli.js.map +1 -1
- package/dist/create_module.d.ts.map +1 -1
- package/dist/create_module.js +1 -33
- package/dist/create_module.js.map +1 -1
- package/dist/create_use_case.d.ts +2 -0
- package/dist/create_use_case.d.ts.map +1 -0
- package/dist/create_use_case.js +266 -0
- package/dist/create_use_case.js.map +1 -0
- package/dist/lib/stringUtils.d.ts +25 -0
- package/dist/lib/stringUtils.d.ts.map +1 -0
- package/dist/lib/stringUtils.js +45 -0
- package/dist/lib/stringUtils.js.map +1 -0
- package/dist/templates/src/lib/types/FailedOperation.ts +3 -3
- package/package.json +6 -2
- package/user-guide.md +197 -0
package/README.md
CHANGED
|
@@ -18,52 +18,38 @@ bun run prepare
|
|
|
18
18
|
npm link
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Commands
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
| Command | Description |
|
|
24
|
+
| ---------------------------------------- | ------------------------------------ |
|
|
25
|
+
| `simpledi new <name>` | Create a new simple-di project |
|
|
26
|
+
| `simpledi module <entity>` | Generate a CRUD module for an entity |
|
|
27
|
+
| `simpledi use-case <name> [imports=...]` | Generate a use case with routes |
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
24
30
|
|
|
25
31
|
```bash
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
# Create project
|
|
33
|
+
simpledi new my-app
|
|
34
|
+
cd my-app
|
|
28
35
|
bun install
|
|
29
|
-
bun run dev
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Generate a module
|
|
33
|
-
|
|
34
|
-
Inside an existing project:
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
# Add your DATABASE_URL to .env.development
|
|
38
|
+
# Generate entities
|
|
37
39
|
simpledi module user
|
|
38
40
|
simpledi module blog-post
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This creates a complete module with:
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
- Module definitions
|
|
47
|
-
- Test file
|
|
48
|
-
- Auto-registers in `schema.ts` and `CoreModule.ts`
|
|
49
|
-
|
|
50
|
-
## Prerequisites
|
|
42
|
+
# Generate use cases
|
|
43
|
+
simpledi use-case get-user imports=user
|
|
44
|
+
simpledi use-case create-blog-post imports=user,blog-post
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Generated projects use [Neon](https://neon.tech) serverless PostgreSQL. You **must** add your connection string to `.env.development`:
|
|
55
|
-
|
|
56
|
-
```env
|
|
57
|
-
DATABASE_URL=postgres://user:password@your-neon-host.neon.tech/dbname?sslmode=require
|
|
46
|
+
# Run
|
|
47
|
+
bun run dev
|
|
58
48
|
```
|
|
59
49
|
|
|
60
|
-
|
|
50
|
+
## Documentation
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
| -------------- | --------------------------------- |
|
|
64
|
-
| `DATABASE_URL` | Neon PostgreSQL connection string |
|
|
65
|
-
| `JWT_SECRET` | Secret key for JWT tokens |
|
|
66
|
-
| `PORT` | Server port (default: 3000) |
|
|
52
|
+
See [user-guide.md](./user-guide.md) for complete documentation.
|
|
67
53
|
|
|
68
54
|
## Project Structure
|
|
69
55
|
|
|
@@ -77,11 +63,30 @@ my-project/
|
|
|
77
63
|
└── src/
|
|
78
64
|
├── AppModule.ts # Root module
|
|
79
65
|
├── schema.ts # Drizzle schema exports
|
|
66
|
+
├── main.routes.ts # Route registrations
|
|
80
67
|
├── core/ # Entity modules (generated)
|
|
81
68
|
├── lib/ # Utilities, types, errors
|
|
82
69
|
└── use-case/ # Use case modules
|
|
83
70
|
```
|
|
84
71
|
|
|
72
|
+
## Prerequisites
|
|
73
|
+
|
|
74
|
+
### Neon PostgreSQL
|
|
75
|
+
|
|
76
|
+
Generated projects use [Neon](https://neon.tech) serverless PostgreSQL. Add your connection string to `.env.development`:
|
|
77
|
+
|
|
78
|
+
```env
|
|
79
|
+
DATABASE_URL=postgres://user:password@your-neon-host.neon.tech/dbname?sslmode=require
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Environment Variables
|
|
83
|
+
|
|
84
|
+
| Variable | Description |
|
|
85
|
+
| -------------- | --------------------------------- |
|
|
86
|
+
| `DATABASE_URL` | Neon PostgreSQL connection string |
|
|
87
|
+
| `JWT_SECRET` | Secret key for JWT tokens |
|
|
88
|
+
| `PORT` | Server port (default: 3000) |
|
|
89
|
+
|
|
85
90
|
## Tech Stack
|
|
86
91
|
|
|
87
92
|
- **Runtime**: [Bun](https://bun.sh)
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { generateSkeleton } from './generate_skeleton.js';
|
|
3
3
|
import { createModule } from './create_module.js';
|
|
4
|
+
import { createUseCase } from './create_use_case.js';
|
|
4
5
|
const args = process.argv.slice(2);
|
|
5
6
|
const command = args[0];
|
|
6
7
|
const name = args[1];
|
|
@@ -9,15 +10,30 @@ function printUsage() {
|
|
|
9
10
|
simpledi - Simple DI App Generator
|
|
10
11
|
|
|
11
12
|
Usage:
|
|
12
|
-
simpledi new <project-name>
|
|
13
|
-
simpledi module <entity-name>
|
|
13
|
+
simpledi new <project-name> Create a new simple-di project
|
|
14
|
+
simpledi module <entity-name> Generate a module in current project
|
|
15
|
+
simpledi use-case <name> [imports=mod1,mod2,...] Generate a use case in current project
|
|
14
16
|
|
|
15
17
|
Examples:
|
|
16
18
|
simpledi new my-app
|
|
17
19
|
simpledi module user
|
|
18
20
|
simpledi module blog-post
|
|
21
|
+
simpledi use-case get-user
|
|
22
|
+
simpledi use-case create-user imports=CoreModule,ConfigModule
|
|
19
23
|
`);
|
|
20
24
|
}
|
|
25
|
+
function parseImports(args) {
|
|
26
|
+
for (const arg of args) {
|
|
27
|
+
if (arg.startsWith('imports=')) {
|
|
28
|
+
const importsStr = arg.slice('imports='.length);
|
|
29
|
+
return importsStr
|
|
30
|
+
.split(',')
|
|
31
|
+
.map((s) => s.trim())
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
21
37
|
async function main() {
|
|
22
38
|
if (!command) {
|
|
23
39
|
printUsage();
|
|
@@ -40,6 +56,15 @@ async function main() {
|
|
|
40
56
|
}
|
|
41
57
|
await createModule(name);
|
|
42
58
|
break;
|
|
59
|
+
case 'use-case':
|
|
60
|
+
if (!name) {
|
|
61
|
+
console.error('Error: Use case name is required');
|
|
62
|
+
console.error('Usage: simpledi use-case <name> [imports=mod1,mod2,...]');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const imports = parseImports(args.slice(2));
|
|
66
|
+
await createUseCase(name, imports);
|
|
67
|
+
break;
|
|
43
68
|
default:
|
|
44
69
|
console.error(`Unknown command: ${command}`);
|
|
45
70
|
printUsage();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAErB,SAAS,UAAU;IACjB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcb,CAAC,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAAc;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,UAAU;iBACd,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,KAAK;YACR,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBACjD,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM;QAER,KAAK,QAAQ;YACX,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBAChD,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;gBACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM;QAER,KAAK,UAAU;YACb,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO,CAAC,KAAK,CACX,yDAAyD,CAC1D,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnC,MAAM;QAER;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,UAAU,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_module.d.ts","sourceRoot":"","sources":["../src/create_module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create_module.d.ts","sourceRoot":"","sources":["../src/create_module.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuajE"}
|
package/dist/create_module.js
CHANGED
|
@@ -1,39 +1,7 @@
|
|
|
1
1
|
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
2
2
|
import { join, resolve } from 'path';
|
|
3
3
|
import { existsSync } from 'fs';
|
|
4
|
-
|
|
5
|
-
function toPascalCase(str) {
|
|
6
|
-
return str
|
|
7
|
-
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase())
|
|
8
|
-
.replace(/[\s-_]+/g, '');
|
|
9
|
-
}
|
|
10
|
-
function toCamelCase(str) {
|
|
11
|
-
const pascal = toPascalCase(str);
|
|
12
|
-
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
13
|
-
}
|
|
14
|
-
function toKebabCase(str) {
|
|
15
|
-
return str
|
|
16
|
-
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
17
|
-
.replace(/[\s_]+/g, '-')
|
|
18
|
-
.toLowerCase();
|
|
19
|
-
}
|
|
20
|
-
function toSnakeCase(str) {
|
|
21
|
-
return str
|
|
22
|
-
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
23
|
-
.replace(/[\s-]+/g, '_')
|
|
24
|
-
.toLowerCase();
|
|
25
|
-
}
|
|
26
|
-
function toUpperSnakeCase(str) {
|
|
27
|
-
return toSnakeCase(str).toUpperCase();
|
|
28
|
-
}
|
|
29
|
-
// Simple pluralizer (naive but works for most standard English words)
|
|
30
|
-
function pluralize(str) {
|
|
31
|
-
if (str.endsWith('y'))
|
|
32
|
-
return str.slice(0, -1) + 'ies';
|
|
33
|
-
if (str.endsWith('s'))
|
|
34
|
-
return str + 'es';
|
|
35
|
-
return str + 's';
|
|
36
|
-
}
|
|
4
|
+
import { toPascalCase, toCamelCase, toKebabCase, toSnakeCase, toUpperSnakeCase, pluralize, } from './lib/stringUtils.js';
|
|
37
5
|
export async function createModule(rawName) {
|
|
38
6
|
if (!rawName) {
|
|
39
7
|
throw new Error('Entity name is required');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_module.js","sourceRoot":"","sources":["../src/create_module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"create_module.js","sourceRoot":"","sources":["../src/create_module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_use_case.d.ts","sourceRoot":"","sources":["../src/create_use_case.ts"],"names":[],"mappings":"AAUA,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAM,EAAO,GACrB,OAAO,CAAC,IAAI,CAAC,CA0Rf"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { toPascalCase, toCamelCase, toKebabCase, toUpperSnakeCase, } from './lib/stringUtils.js';
|
|
5
|
+
export async function createUseCase(rawName, imports = []) {
|
|
6
|
+
if (!rawName) {
|
|
7
|
+
throw new Error('Use case name is required');
|
|
8
|
+
}
|
|
9
|
+
const EntityName = toPascalCase(rawName); // e.g. GetUser
|
|
10
|
+
const entityName = toCamelCase(rawName); // e.g. getUser
|
|
11
|
+
const kebabName = toKebabCase(rawName); // e.g. get-user
|
|
12
|
+
const TOKEN_BASE = toUpperSnakeCase(rawName); // e.g. GET_USER
|
|
13
|
+
console.log(`Creating use case: ${EntityName}`);
|
|
14
|
+
console.log(`Directory: src/use-case/${kebabName}`);
|
|
15
|
+
if (imports.length > 0) {
|
|
16
|
+
console.log(`Imports: ${imports.join(', ')}`);
|
|
17
|
+
}
|
|
18
|
+
const srcDir = resolve(process.cwd(), 'src');
|
|
19
|
+
const targetDir = resolve(srcDir, 'use-case', kebabName);
|
|
20
|
+
const outputsDir = resolve(targetDir, 'outputs');
|
|
21
|
+
if (existsSync(targetDir)) {
|
|
22
|
+
throw new Error(`Directory ${targetDir} already exists`);
|
|
23
|
+
}
|
|
24
|
+
await mkdir(targetDir, { recursive: true });
|
|
25
|
+
await mkdir(outputsDir, { recursive: true });
|
|
26
|
+
// Build module imports from entity names
|
|
27
|
+
// e.g., "user" -> import { UserModule } from '@root/core/user/UserModule';
|
|
28
|
+
const moduleImports = imports.map((entityName) => {
|
|
29
|
+
const pascalName = toPascalCase(entityName);
|
|
30
|
+
const kebab = toKebabCase(entityName);
|
|
31
|
+
return {
|
|
32
|
+
moduleName: `${pascalName}Module`,
|
|
33
|
+
importPath: `@root/core/${kebab}/${pascalName}Module`,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
// Generate import statements for the use case file
|
|
37
|
+
const moduleImportStatements = moduleImports
|
|
38
|
+
.map((m) => `import { ${m.moduleName} } from '${m.importPath}';`)
|
|
39
|
+
.join('\n');
|
|
40
|
+
// Generate the imports array content
|
|
41
|
+
const moduleImportsArray = moduleImports.map((m) => m.moduleName).join(', ');
|
|
42
|
+
// 1. <Name>Success.ts (Output)
|
|
43
|
+
const successContent = `import { SuccessfullOperation } from '@root/lib';
|
|
44
|
+
|
|
45
|
+
export type ${EntityName}Payload = {
|
|
46
|
+
// TODO: Define payload properties
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export class ${EntityName}Success extends SuccessfullOperation {
|
|
50
|
+
constructor(
|
|
51
|
+
result: ${EntityName}Payload,
|
|
52
|
+
message: string = '${EntityName} executed successfully',
|
|
53
|
+
) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.result = result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
// 2. <Name>Failure.ts (Output)
|
|
60
|
+
const failureContent = `import { FailedOperation } from '@root/lib';
|
|
61
|
+
|
|
62
|
+
export class ${EntityName}Failure extends FailedOperation {
|
|
63
|
+
constructor(
|
|
64
|
+
message: string = '${EntityName} failed to execute',
|
|
65
|
+
) {
|
|
66
|
+
super(message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
// 3. <Name>.ts (Use Case Class + Module)
|
|
71
|
+
const useCaseContent = `import { Module, Service } from '@kanian77/simple-di';
|
|
72
|
+
import {
|
|
73
|
+
${EntityName}Success,
|
|
74
|
+
type ${EntityName}Payload,
|
|
75
|
+
} from './outputs/${EntityName}Success';
|
|
76
|
+
import type { IUseCase } from '../IUseCase';
|
|
77
|
+
${moduleImportStatements ? moduleImportStatements + '\n' : ''}
|
|
78
|
+
export const ${TOKEN_BASE}_USE_CASE_TOKEN = '${TOKEN_BASE}_USE_CASE';
|
|
79
|
+
|
|
80
|
+
@Service({
|
|
81
|
+
token: ${TOKEN_BASE}_USE_CASE_TOKEN,
|
|
82
|
+
lifecycle: 'transient',
|
|
83
|
+
})
|
|
84
|
+
export class ${EntityName} implements IUseCase {
|
|
85
|
+
constructor() {}
|
|
86
|
+
|
|
87
|
+
async execute(): Promise<${EntityName}Success> {
|
|
88
|
+
const result: ${EntityName}Payload = {
|
|
89
|
+
// TODO: Implement use case logic
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return new ${EntityName}Success(result);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const ${EntityName}Module = new Module({
|
|
97
|
+
imports: [${moduleImportsArray}],
|
|
98
|
+
providers: [
|
|
99
|
+
{
|
|
100
|
+
provide: ${TOKEN_BASE}_USE_CASE_TOKEN,
|
|
101
|
+
useClass: ${EntityName},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
`;
|
|
106
|
+
// 4. <name>Routes.ts (Route Handler)
|
|
107
|
+
const routesContent = `import { Hono } from 'hono';
|
|
108
|
+
import { StatusCodes } from 'http-status-codes';
|
|
109
|
+
import { inject } from '@kanian77/simple-di';
|
|
110
|
+
import { ${EntityName}, ${TOKEN_BASE}_USE_CASE_TOKEN } from './${EntityName}';
|
|
111
|
+
import { ${EntityName}Failure } from './outputs/${EntityName}Failure';
|
|
112
|
+
|
|
113
|
+
const ${entityName}Routes = new Hono();
|
|
114
|
+
|
|
115
|
+
${entityName}Routes.get('/', async (c) => {
|
|
116
|
+
try {
|
|
117
|
+
const useCase = inject<${EntityName}>(${TOKEN_BASE}_USE_CASE_TOKEN);
|
|
118
|
+
const result = await useCase.execute();
|
|
119
|
+
|
|
120
|
+
return c.json(result, StatusCodes.OK);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.error('Error in ${entityName}Routes:', e);
|
|
123
|
+
return c.json(
|
|
124
|
+
new ${EntityName}Failure('Internal Server Error'),
|
|
125
|
+
StatusCodes.INTERNAL_SERVER_ERROR,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const ${entityName}RoutesPath = '/${kebabName}';
|
|
131
|
+
|
|
132
|
+
export { ${entityName}Routes, ${entityName}RoutesPath };
|
|
133
|
+
`;
|
|
134
|
+
// Write files
|
|
135
|
+
const files = [
|
|
136
|
+
{
|
|
137
|
+
path: join(outputsDir, `${EntityName}Success.ts`),
|
|
138
|
+
content: successContent,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
path: join(outputsDir, `${EntityName}Failure.ts`),
|
|
142
|
+
content: failureContent,
|
|
143
|
+
},
|
|
144
|
+
{ path: join(targetDir, `${EntityName}.ts`), content: useCaseContent },
|
|
145
|
+
{ path: join(targetDir, `${entityName}Routes.ts`), content: routesContent },
|
|
146
|
+
];
|
|
147
|
+
for (const file of files) {
|
|
148
|
+
await writeFile(file.path, file.content);
|
|
149
|
+
console.log(`Created: ${file.path.replace(process.cwd() + '/', '')}`);
|
|
150
|
+
}
|
|
151
|
+
// Auto-Registration
|
|
152
|
+
// 1. src/use-case/UseCaseModule.ts
|
|
153
|
+
const useCaseModulePath = join(srcDir, 'use-case', 'UseCaseModule.ts');
|
|
154
|
+
if (existsSync(useCaseModulePath)) {
|
|
155
|
+
let content = await readFile(useCaseModulePath, 'utf8');
|
|
156
|
+
const importStatement = `import { ${EntityName}Module } from './${kebabName}/${EntityName}';`;
|
|
157
|
+
if (!content.includes(importStatement)) {
|
|
158
|
+
// Add import after last import
|
|
159
|
+
const lastImportIndex = content.lastIndexOf('import ');
|
|
160
|
+
if (lastImportIndex !== -1) {
|
|
161
|
+
const nextLineIndex = content.indexOf('\n', lastImportIndex);
|
|
162
|
+
content =
|
|
163
|
+
content.slice(0, nextLineIndex + 1) +
|
|
164
|
+
importStatement +
|
|
165
|
+
'\n' +
|
|
166
|
+
content.slice(nextLineIndex + 1);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
content = importStatement + '\n' + content;
|
|
170
|
+
}
|
|
171
|
+
// Add to imports array
|
|
172
|
+
const importsRegex = /imports:\s*\[/g;
|
|
173
|
+
const match = importsRegex.exec(content);
|
|
174
|
+
if (match) {
|
|
175
|
+
const arrayStart = match.index + match[0].length;
|
|
176
|
+
let depth = 1;
|
|
177
|
+
let endIndex = -1;
|
|
178
|
+
for (let i = arrayStart; i < content.length; i++) {
|
|
179
|
+
if (content[i] === '[')
|
|
180
|
+
depth++;
|
|
181
|
+
if (content[i] === ']')
|
|
182
|
+
depth--;
|
|
183
|
+
if (depth === 0) {
|
|
184
|
+
endIndex = i;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (endIndex !== -1) {
|
|
189
|
+
const arrayContent = content.slice(arrayStart, endIndex);
|
|
190
|
+
if (!arrayContent.includes(`${EntityName}Module`)) {
|
|
191
|
+
const trimmed = arrayContent.trim();
|
|
192
|
+
const hasTrailingComma = trimmed.endsWith(',');
|
|
193
|
+
const separator = trimmed.length > 0 && !hasTrailingComma ? ', ' : '';
|
|
194
|
+
const insertion = `${separator}${EntityName}Module`;
|
|
195
|
+
content =
|
|
196
|
+
content.slice(0, endIndex) + insertion + content.slice(endIndex);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
await writeFile(useCaseModulePath, content);
|
|
201
|
+
console.log(`Updated: src/use-case/UseCaseModule.ts`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.warn('Warning: src/use-case/UseCaseModule.ts not found');
|
|
206
|
+
}
|
|
207
|
+
// 2. src/main.routes.ts
|
|
208
|
+
const mainRoutesPath = join(srcDir, 'main.routes.ts');
|
|
209
|
+
if (existsSync(mainRoutesPath)) {
|
|
210
|
+
let content = await readFile(mainRoutesPath, 'utf8');
|
|
211
|
+
const importStatement = `import {\n ${entityName}Routes,\n ${entityName}RoutesPath,\n} from './use-case/${kebabName}/${entityName}Routes';`;
|
|
212
|
+
if (!content.includes(`${entityName}Routes`)) {
|
|
213
|
+
// Add import after last import
|
|
214
|
+
const lastImportIndex = content.lastIndexOf('import ');
|
|
215
|
+
if (lastImportIndex !== -1) {
|
|
216
|
+
// Find the end of this import (could be multi-line)
|
|
217
|
+
let searchPos = lastImportIndex;
|
|
218
|
+
let importEndIndex = -1;
|
|
219
|
+
// Look for the semicolon that ends the import
|
|
220
|
+
while (searchPos < content.length) {
|
|
221
|
+
if (content[searchPos] === ';') {
|
|
222
|
+
importEndIndex = searchPos;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
searchPos++;
|
|
226
|
+
}
|
|
227
|
+
if (importEndIndex !== -1) {
|
|
228
|
+
content =
|
|
229
|
+
content.slice(0, importEndIndex + 1) +
|
|
230
|
+
'\n' +
|
|
231
|
+
importStatement +
|
|
232
|
+
content.slice(importEndIndex + 1);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
content = importStatement + '\n' + content;
|
|
237
|
+
}
|
|
238
|
+
// Add route registration before export
|
|
239
|
+
const routeRegistration = `mainRoutes.route(${entityName}RoutesPath, ${entityName}Routes);`;
|
|
240
|
+
if (!content.includes(routeRegistration)) {
|
|
241
|
+
// Find line before 'export { mainRoutes }'
|
|
242
|
+
const exportIndex = content.indexOf('export { mainRoutes }');
|
|
243
|
+
if (exportIndex !== -1) {
|
|
244
|
+
content =
|
|
245
|
+
content.slice(0, exportIndex) +
|
|
246
|
+
routeRegistration +
|
|
247
|
+
'\n\n' +
|
|
248
|
+
content.slice(exportIndex);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
// Fallback: add before last line
|
|
252
|
+
const lines = content.split('\n');
|
|
253
|
+
lines.splice(lines.length - 1, 0, routeRegistration);
|
|
254
|
+
content = lines.join('\n');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
await writeFile(mainRoutesPath, content);
|
|
258
|
+
console.log(`Updated: src/main.routes.ts`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.warn('Warning: src/main.routes.ts not found');
|
|
263
|
+
}
|
|
264
|
+
console.log('\n✅ Use case generation complete!');
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=create_use_case.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_use_case.js","sourceRoot":"","sources":["../src/create_use_case.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String manipulation utilities for code generation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert string to PascalCase (e.g., "blog-post" -> "BlogPost")
|
|
6
|
+
*/
|
|
7
|
+
export declare function toPascalCase(str: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Convert string to camelCase (e.g., "blog-post" -> "blogPost")
|
|
10
|
+
*/
|
|
11
|
+
export declare function toCamelCase(str: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Convert string to kebab-case (e.g., "BlogPost" -> "blog-post")
|
|
14
|
+
*/
|
|
15
|
+
export declare function toKebabCase(str: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Convert string to snake_case (e.g., "BlogPost" -> "blog_post")
|
|
18
|
+
*/
|
|
19
|
+
export declare function toSnakeCase(str: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Convert string to UPPER_SNAKE_CASE (e.g., "BlogPost" -> "BLOG_POST")
|
|
22
|
+
*/
|
|
23
|
+
export declare function toUpperSnakeCase(str: string): string;
|
|
24
|
+
export { default as pluralize } from 'pluralize';
|
|
25
|
+
//# sourceMappingURL=stringUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringUtils.d.ts","sourceRoot":"","sources":["../../src/lib/stringUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpD;AAGD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String manipulation utilities for code generation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert string to PascalCase (e.g., "blog-post" -> "BlogPost")
|
|
6
|
+
*/
|
|
7
|
+
export function toPascalCase(str) {
|
|
8
|
+
return str
|
|
9
|
+
.replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase())
|
|
10
|
+
.replace(/[\s-_]+/g, '');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Convert string to camelCase (e.g., "blog-post" -> "blogPost")
|
|
14
|
+
*/
|
|
15
|
+
export function toCamelCase(str) {
|
|
16
|
+
const pascal = toPascalCase(str);
|
|
17
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert string to kebab-case (e.g., "BlogPost" -> "blog-post")
|
|
21
|
+
*/
|
|
22
|
+
export function toKebabCase(str) {
|
|
23
|
+
return str
|
|
24
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
25
|
+
.replace(/[\s_]+/g, '-')
|
|
26
|
+
.toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Convert string to snake_case (e.g., "BlogPost" -> "blog_post")
|
|
30
|
+
*/
|
|
31
|
+
export function toSnakeCase(str) {
|
|
32
|
+
return str
|
|
33
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
34
|
+
.replace(/[\s-]+/g, '_')
|
|
35
|
+
.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Convert string to UPPER_SNAKE_CASE (e.g., "BlogPost" -> "BLOG_POST")
|
|
39
|
+
*/
|
|
40
|
+
export function toUpperSnakeCase(str) {
|
|
41
|
+
return toSnakeCase(str).toUpperCase();
|
|
42
|
+
}
|
|
43
|
+
// Re-export pluralize from npm package for better handling of irregular plurals
|
|
44
|
+
export { default as pluralize } from 'pluralize';
|
|
45
|
+
//# sourceMappingURL=stringUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringUtils.js","sourceRoot":"","sources":["../../src/lib/stringUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,GAAG;SACP,OAAO,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;SAC5D,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACxC,CAAC;AAED,gFAAgF;AAChF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { OperationResult } from './OperationResult';
|
|
2
2
|
|
|
3
3
|
export class FailedOperation extends OperationResult {
|
|
4
|
-
public readonly success = false;
|
|
5
|
-
public readonly result = null;
|
|
6
|
-
constructor(readonly message = 'Failed Operation') {
|
|
4
|
+
public override readonly success = false;
|
|
5
|
+
public override readonly result = null;
|
|
6
|
+
constructor(public override readonly message = 'Failed Operation') {
|
|
7
7
|
super();
|
|
8
8
|
}
|
|
9
9
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simpledi-app-generator",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "generates a @kanian77/simple-di app",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Patrick Assoa Adou",
|
|
@@ -33,9 +33,13 @@
|
|
|
33
33
|
"release": "bun run prepare && npm publish --userconfig .npmrc --access public"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@types/bun": "latest"
|
|
36
|
+
"@types/bun": "latest",
|
|
37
|
+
"@types/pluralize": "^0.0.33"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
40
|
"typescript": "^5"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"pluralize": "^8.0.0"
|
|
40
44
|
}
|
|
41
45
|
}
|
package/user-guide.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# simpledi-app-generator User Guide
|
|
2
|
+
|
|
3
|
+
Complete guide for using the simpledi-app-generator CLI to create and extend simple-di applications.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install globally
|
|
9
|
+
npm install -g simpledi-app-generator
|
|
10
|
+
|
|
11
|
+
# Create a new project
|
|
12
|
+
simpledi new my-app
|
|
13
|
+
cd my-app
|
|
14
|
+
bun install
|
|
15
|
+
bun run dev
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
### `simpledi new <project-name>`
|
|
23
|
+
|
|
24
|
+
Creates a new simple-di project with a complete backend structure.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
simpledi new my-app
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Generated structure:**
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
my-app/
|
|
34
|
+
├── main.ts # Application entry point
|
|
35
|
+
├── config/ # Configuration module
|
|
36
|
+
├── db/ # Database service module
|
|
37
|
+
└── src/
|
|
38
|
+
├── AppModule.ts # Root DI module
|
|
39
|
+
├── schema.ts # Drizzle schema exports
|
|
40
|
+
├── main.routes.ts # Route registrations
|
|
41
|
+
├── core/ # Entity modules
|
|
42
|
+
│ └── CoreModule.ts
|
|
43
|
+
├── lib/ # Utilities, types, errors
|
|
44
|
+
└── use-case/ # Use case modules
|
|
45
|
+
├── IUseCase.ts
|
|
46
|
+
├── UseCaseModule.ts
|
|
47
|
+
└── health-check/
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### `simpledi module <entity-name>`
|
|
53
|
+
|
|
54
|
+
Generates a complete CRUD module for an entity inside an existing project.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
simpledi module user
|
|
58
|
+
simpledi module blog-post
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Generated files** in `src/core/<entity-name>/`:
|
|
62
|
+
|
|
63
|
+
| File | Purpose |
|
|
64
|
+
| ----------------------------- | ------------------------------- |
|
|
65
|
+
| `baseZod<Entity>Schema.ts` | Zod schema with base properties |
|
|
66
|
+
| `<Entity>.ts` | Drizzle table schema |
|
|
67
|
+
| `I<Entity>Repository.ts` | Repository interface |
|
|
68
|
+
| `<Entity>Repository.ts` | Repository implementation |
|
|
69
|
+
| `<Entity>RepositoryModule.ts` | Repository DI module |
|
|
70
|
+
| `I<Entity>Service.ts` | Service interface |
|
|
71
|
+
| `<Entity>Service.ts` | Service implementation |
|
|
72
|
+
| `<Entity>ServiceModule.ts` | Service DI module |
|
|
73
|
+
| `<Entity>Module.ts` | Main module (combines all) |
|
|
74
|
+
| `<Entity>Repository.spec.ts` | Test file |
|
|
75
|
+
|
|
76
|
+
**Auto-registration:**
|
|
77
|
+
|
|
78
|
+
- Adds export to `src/schema.ts`
|
|
79
|
+
- Adds module to `src/core/CoreModule.ts`
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### `simpledi use-case <name> [imports=entity1,entity2,...]`
|
|
84
|
+
|
|
85
|
+
Generates a use case with routes and typed outputs.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Simple use case
|
|
89
|
+
simpledi use-case get-user
|
|
90
|
+
|
|
91
|
+
# Use case with module imports
|
|
92
|
+
simpledi use-case get-user imports=user
|
|
93
|
+
simpledi use-case create-blog-post imports=user,blog-post
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Generated files** in `src/use-case/<name>/`:
|
|
97
|
+
|
|
98
|
+
| File | Purpose |
|
|
99
|
+
| -------------------------- | ---------------------------------------------------------- |
|
|
100
|
+
| `<Name>.ts` | Use case class with `@Service` decorator and Module export |
|
|
101
|
+
| `<name>Routes.ts` | Hono route handler |
|
|
102
|
+
| `outputs/<Name>Success.ts` | Typed success response + payload type |
|
|
103
|
+
| `outputs/<Name>Failure.ts` | Typed failure response |
|
|
104
|
+
|
|
105
|
+
**Auto-registration:**
|
|
106
|
+
|
|
107
|
+
- Adds module to `src/use-case/UseCaseModule.ts`
|
|
108
|
+
- Adds routes to `src/main.routes.ts`
|
|
109
|
+
|
|
110
|
+
**Imports parameter:**
|
|
111
|
+
|
|
112
|
+
When you specify `imports=user`, the generator:
|
|
113
|
+
|
|
114
|
+
1. Converts entity name to module: `user` → `UserModule`
|
|
115
|
+
2. Generates import path: `@root/core/user/UserModule`
|
|
116
|
+
3. Adds to the module's imports array
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Response Pattern
|
|
121
|
+
|
|
122
|
+
All use cases return standardized response objects:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Success response
|
|
126
|
+
class SuccessfullOperation {
|
|
127
|
+
success = true;
|
|
128
|
+
message: string;
|
|
129
|
+
result: any;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Failure response
|
|
133
|
+
class FailedOperation {
|
|
134
|
+
success = false;
|
|
135
|
+
message: string;
|
|
136
|
+
result = null;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Your generated use case outputs extend these base classes:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// Success
|
|
144
|
+
export class GetUserSuccess extends SuccessfullOperation {
|
|
145
|
+
constructor(
|
|
146
|
+
result: GetUserPayload,
|
|
147
|
+
message = 'GetUser executed successfully',
|
|
148
|
+
) {
|
|
149
|
+
super(message);
|
|
150
|
+
this.result = result;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Failure
|
|
155
|
+
export class GetUserFailure extends FailedOperation {
|
|
156
|
+
constructor(message = 'GetUser failed to execute') {
|
|
157
|
+
super(message);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Development Setup
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Clone and setup
|
|
168
|
+
git clone <repo>
|
|
169
|
+
cd simpledi-app-generator
|
|
170
|
+
bun install
|
|
171
|
+
bun run prepare
|
|
172
|
+
npm link
|
|
173
|
+
|
|
174
|
+
# Make changes and rebuild
|
|
175
|
+
bun run prepare
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Environment Variables
|
|
181
|
+
|
|
182
|
+
| Variable | Description |
|
|
183
|
+
| -------------- | --------------------------------- |
|
|
184
|
+
| `DATABASE_URL` | Neon PostgreSQL connection string |
|
|
185
|
+
| `JWT_SECRET` | Secret key for JWT tokens |
|
|
186
|
+
| `PORT` | Server port (default: 3000) |
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Tech Stack
|
|
191
|
+
|
|
192
|
+
- **Runtime**: [Bun](https://bun.sh)
|
|
193
|
+
- **Framework**: [Hono](https://hono.dev)
|
|
194
|
+
- **DI**: [@kanian77/simple-di](https://www.npmjs.com/package/@kanian77/simple-di)
|
|
195
|
+
- **ORM**: [Drizzle](https://orm.drizzle.team)
|
|
196
|
+
- **Database**: [Neon PostgreSQL](https://neon.tech)
|
|
197
|
+
- **Validation**: [Zod](https://zod.dev)
|