@bogomolcompany/bogo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/generate-module.d.ts +4 -0
- package/dist/commands/generate-module.d.ts.map +1 -0
- package/dist/commands/generate-module.js +56 -0
- package/dist/commands/generate-module.js.map +1 -0
- package/dist/templates/module.d.ts +8 -0
- package/dist/templates/module.d.ts.map +1 -0
- package/dist/templates/module.js +114 -0
- package/dist/templates/module.js.map +1 -0
- package/dist/utils/config.d.ts +4 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +27 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/naming.d.ts +8 -0
- package/dist/utils/naming.d.ts.map +1 -0
- package/dist/utils/naming.js +43 -0
- package/dist/utils/naming.js.map +1 -0
- package/dist/utils/patch-index.d.ts +4 -0
- package/dist/utils/patch-index.d.ts.map +1 -0
- package/dist/utils/patch-index.js +58 -0
- package/dist/utils/patch-index.js.map +1 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @bogomolcompany/bogo
|
|
2
|
+
|
|
3
|
+
CLI-генератор модулей Express API: controller, service, dto, routes, validator.
|
|
4
|
+
|
|
5
|
+
Отдельный npm-пакет, не привязан к конкретному проекту. Настраивается через `.bogorc.json` в целевом репозитории.
|
|
6
|
+
|
|
7
|
+
## Установка
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @bogomolcompany/bogo
|
|
11
|
+
# или локально в проекте
|
|
12
|
+
npm install --save-dev @bogomolcompany/bogo
|
|
13
|
+
npx bogo --help
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Из исходников:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git clone <repo-url> bogo-cli
|
|
20
|
+
cd bogo-cli
|
|
21
|
+
npm install
|
|
22
|
+
npm run build
|
|
23
|
+
npm link
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Инициализация в проекте
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd /path/to/your-express-app
|
|
30
|
+
bogo init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Создаёт `.bogorc.json`:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"apiDir": "src/api",
|
|
38
|
+
"indexFile": "src/index.ts",
|
|
39
|
+
"routePrefix": "/api"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Генерация модуля
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bogo g module analytics -m getStats -m getReport
|
|
47
|
+
bogo g module orders -m createOrder:/create -m getOrder:/:id
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Создаёт:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
src/api/analytics/
|
|
54
|
+
analytics.controller.ts
|
|
55
|
+
analytics.service.ts
|
|
56
|
+
analytics.dto.ts
|
|
57
|
+
analytics.validator.ts
|
|
58
|
+
analytics.routes.ts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
И дописывает import + `app.use` в `src/index.ts` (если файл найден).
|
|
62
|
+
|
|
63
|
+
## Опции
|
|
64
|
+
|
|
65
|
+
| Флаг | Описание |
|
|
66
|
+
|------|----------|
|
|
67
|
+
| `-m, --method` | Метод контроллера. Повторяемый. Формат: `getList` или `getList:/custom-path` |
|
|
68
|
+
| `--skip-index` | Не править index-файл |
|
|
69
|
+
|
|
70
|
+
## Требования к целевому проекту
|
|
71
|
+
|
|
72
|
+
- Express + TypeScript
|
|
73
|
+
- Zod для валидации
|
|
74
|
+
- Middleware `validate` по пути `src/middlewares/validate`
|
|
75
|
+
- `res.success` / `res.error` через middleware ответа
|
|
76
|
+
|
|
77
|
+
## Разработка пакета
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm run build
|
|
81
|
+
npm run dev -- init
|
|
82
|
+
npm run dev -- g module test -m getList
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Публикация
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm publish
|
|
89
|
+
```
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const generate_module_1 = require("./commands/generate-module");
|
|
6
|
+
const program = new commander_1.Command();
|
|
7
|
+
program.name("bogo").description("CLI generator for Express API modules").version("0.1.0");
|
|
8
|
+
program
|
|
9
|
+
.command("init")
|
|
10
|
+
.description("Create .bogorc.json in the current directory")
|
|
11
|
+
.action(() => {
|
|
12
|
+
try {
|
|
13
|
+
(0, generate_module_1.runInit)(process.cwd());
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.error(error instanceof Error ? error.message : error);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
program
|
|
21
|
+
.command("generate")
|
|
22
|
+
.alias("g")
|
|
23
|
+
.description("Generate code scaffolding")
|
|
24
|
+
.argument("<type>", "resource type (module)")
|
|
25
|
+
.argument("<name>", "resource name, e.g. users or user-profile")
|
|
26
|
+
.option("-m, --method <method>", "method name (repeatable), format: getList or getList:/custom-path", collect, [])
|
|
27
|
+
.option("--skip-index", "do not patch index file", false)
|
|
28
|
+
.action((type, name, options) => {
|
|
29
|
+
try {
|
|
30
|
+
if (type !== "module") {
|
|
31
|
+
throw new Error(`Unknown type "${type}". Available: module`);
|
|
32
|
+
}
|
|
33
|
+
(0, generate_module_1.runGenerateModule)(process.cwd(), name, {
|
|
34
|
+
methods: options.method,
|
|
35
|
+
skipIndex: options.skipIndex,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(error instanceof Error ? error.message : error);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
function collect(value, previous) {
|
|
44
|
+
return previous.concat([value]);
|
|
45
|
+
}
|
|
46
|
+
program.parse();
|
|
47
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,gEAAwE;AAExE,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE3F,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,GAAG,EAAE;IACX,IAAI,CAAC;QACH,IAAA,yBAAO,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,2BAA2B,CAAC;KACxC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC;KAC5C,QAAQ,CAAC,QAAQ,EAAE,2CAA2C,CAAC;KAC/D,MAAM,CAAC,uBAAuB,EAAE,mEAAmE,EAAE,OAAO,EAAE,EAAE,CAAC;KACjH,MAAM,CAAC,cAAc,EAAE,yBAAyB,EAAE,KAAK,CAAC;KACxD,MAAM,CAAC,CAAC,IAAY,EAAE,IAAY,EAAE,OAAiD,EAAE,EAAE;IACxF,IAAI,CAAC;QACH,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,sBAAsB,CAAC,CAAC;QAC/D,CAAC;QACD,IAAA,mCAAiB,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE;YACrC,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,SAAS,OAAO,CAAC,KAAa,EAAE,QAAkB;IAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-module.d.ts","sourceRoot":"","sources":["../../src/commands/generate-module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAc,MAAM,eAAe,CAAC;AAiBlE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAUzC;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CA6BvG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runInit = runInit;
|
|
4
|
+
exports.runGenerateModule = runGenerateModule;
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const module_1 = require("../templates/module");
|
|
8
|
+
const config_1 = require("../utils/config");
|
|
9
|
+
const naming_1 = require("../utils/naming");
|
|
10
|
+
const patch_index_1 = require("../utils/patch-index");
|
|
11
|
+
function parseMethodSpec(raw) {
|
|
12
|
+
const [name, route] = raw.split(":");
|
|
13
|
+
if (!name || !/^[a-zA-Z][a-zA-Z0-9]*$/.test(name)) {
|
|
14
|
+
throw new Error(`Invalid method name: "${raw}". Use camelCase, e.g. getList or getList:/custom-path`);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
name,
|
|
18
|
+
route: route ? (0, naming_1.methodToRoutePath)(name, route) : undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function runInit(cwd) {
|
|
22
|
+
const configPath = (0, path_1.join)(cwd, ".bogorc.json");
|
|
23
|
+
if ((0, fs_1.existsSync)(configPath)) {
|
|
24
|
+
console.log(`.bogorc.json already exists at ${configPath}`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
(0, fs_1.writeFileSync)(configPath, (0, config_1.getDefaultConfigContent)(), "utf-8");
|
|
28
|
+
console.log(`Created ${configPath}`);
|
|
29
|
+
}
|
|
30
|
+
function runGenerateModule(cwd, moduleName, options) {
|
|
31
|
+
const config = (0, config_1.loadConfig)(cwd);
|
|
32
|
+
const names = (0, naming_1.resolveModuleNames)(moduleName);
|
|
33
|
+
const methods = options.methods.length > 0 ? options.methods.map(parseMethodSpec) : [{ name: "execute" }];
|
|
34
|
+
const targetDir = (0, path_1.join)(cwd, config.apiDir, names.kebab);
|
|
35
|
+
const indexPath = (0, path_1.join)(cwd, config.indexFile);
|
|
36
|
+
if ((0, fs_1.existsSync)(targetDir)) {
|
|
37
|
+
throw new Error(`Module directory already exists: ${targetDir}`);
|
|
38
|
+
}
|
|
39
|
+
const written = (0, module_1.writeModuleFiles)(targetDir, { names, methods });
|
|
40
|
+
console.log(`Module "${names.kebab}" created:\n`);
|
|
41
|
+
for (const file of written) {
|
|
42
|
+
console.log(` ${file}`);
|
|
43
|
+
}
|
|
44
|
+
if (options.skipIndex) {
|
|
45
|
+
console.log(`\nSkipped index patch (--skip-index)`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const patched = (0, patch_index_1.patchIndexFile)(indexPath, names, config.routePrefix);
|
|
49
|
+
if (patched) {
|
|
50
|
+
console.log(`\nUpdated ${indexPath}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log(`\n${(0, patch_index_1.suggestIndexPatch)(names, config.routePrefix)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=generate-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-module.js","sourceRoot":"","sources":["../../src/commands/generate-module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModuleTemplateContext } from "../interfaces";
|
|
2
|
+
export declare function renderController(ctx: ModuleTemplateContext): string;
|
|
3
|
+
export declare function renderService(ctx: ModuleTemplateContext): string;
|
|
4
|
+
export declare function renderDto(ctx: ModuleTemplateContext): string;
|
|
5
|
+
export declare function renderValidator(ctx: ModuleTemplateContext): string;
|
|
6
|
+
export declare function renderRoutes(ctx: ModuleTemplateContext): string;
|
|
7
|
+
export declare function writeModuleFiles(targetDir: string, ctx: ModuleTemplateContext): string[];
|
|
8
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/templates/module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGtD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAwBnE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAsBhE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAS5D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAalE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAsB/D;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAyBxF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderController = renderController;
|
|
4
|
+
exports.renderService = renderService;
|
|
5
|
+
exports.renderDto = renderDto;
|
|
6
|
+
exports.renderValidator = renderValidator;
|
|
7
|
+
exports.renderRoutes = renderRoutes;
|
|
8
|
+
exports.writeModuleFiles = writeModuleFiles;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const naming_1 = require("../utils/naming");
|
|
12
|
+
function renderController(ctx) {
|
|
13
|
+
const { names, methods } = ctx;
|
|
14
|
+
const methodsCode = methods
|
|
15
|
+
.map(method => `
|
|
16
|
+
async ${method.name}(req: e.Request, res: e.Response) {
|
|
17
|
+
try {
|
|
18
|
+
const result = await ${names.pascal}Service.${method.name}(req.body);
|
|
19
|
+
return res.success(result);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return res.error(error);
|
|
22
|
+
}
|
|
23
|
+
}`)
|
|
24
|
+
.join("\n");
|
|
25
|
+
return `import e from "express";
|
|
26
|
+
import ${names.pascal}Service from "./${names.kebab}.service";
|
|
27
|
+
|
|
28
|
+
class ${names.pascal}Controller {${methodsCode}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default new ${names.pascal}Controller();
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
function renderService(ctx) {
|
|
35
|
+
const { names, methods } = ctx;
|
|
36
|
+
const imports = methods.length > 0
|
|
37
|
+
? `import { ${methods.map(m => `${m.name}DTO`).join(", ")} } from "./${names.kebab}.dto";\n`
|
|
38
|
+
: "";
|
|
39
|
+
const methodsCode = methods
|
|
40
|
+
.map(method => `
|
|
41
|
+
async ${method.name}(body: ${method.name}DTO) {
|
|
42
|
+
throw new Error("${names.pascal}Service.${method.name} is not implemented");
|
|
43
|
+
}`)
|
|
44
|
+
.join("\n");
|
|
45
|
+
return `${imports}
|
|
46
|
+
class ${names.pascal}Service {${methodsCode}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default new ${names.pascal}Service();
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
function renderDto(ctx) {
|
|
53
|
+
const blocks = ctx.methods.map(method => `export interface ${method.name}DTO {
|
|
54
|
+
// TODO: define fields
|
|
55
|
+
}
|
|
56
|
+
`);
|
|
57
|
+
return blocks.join("\n");
|
|
58
|
+
}
|
|
59
|
+
function renderValidator(ctx) {
|
|
60
|
+
const exports = ctx.methods.map(method => `export const ${method.name} = z.object({
|
|
61
|
+
body: z.object({
|
|
62
|
+
// TODO: define validation schema
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
`);
|
|
66
|
+
return `import { z } from "zod";
|
|
67
|
+
|
|
68
|
+
${exports.join("\n")}`;
|
|
69
|
+
}
|
|
70
|
+
function renderRoutes(ctx) {
|
|
71
|
+
const { names, methods } = ctx;
|
|
72
|
+
const validatorImports = methods.map(m => m.name).join(", ");
|
|
73
|
+
const routes = methods
|
|
74
|
+
.map(method => {
|
|
75
|
+
const routePath = (0, naming_1.methodToRoutePath)(method.name, method.route);
|
|
76
|
+
return `router.post("${routePath}", validate(${method.name}), (req: Request, res: Response) => controller.${method.name}(req, res));`;
|
|
77
|
+
})
|
|
78
|
+
.join("\n");
|
|
79
|
+
return `import { Request, Response, Router } from "express";
|
|
80
|
+
import { validate } from "../../middlewares/validate";
|
|
81
|
+
import ${names.pascal}Controller from "./${names.kebab}.controller";
|
|
82
|
+
import { ${validatorImports} } from "./${names.kebab}.validator";
|
|
83
|
+
|
|
84
|
+
const router = Router();
|
|
85
|
+
const controller = ${names.pascal}Controller;
|
|
86
|
+
|
|
87
|
+
${routes}
|
|
88
|
+
|
|
89
|
+
export default router;
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
function writeModuleFiles(targetDir, ctx) {
|
|
93
|
+
if (!(0, fs_1.existsSync)(targetDir)) {
|
|
94
|
+
(0, fs_1.mkdirSync)(targetDir, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
const files = [
|
|
97
|
+
[`${ctx.names.kebab}.controller.ts`, renderController(ctx)],
|
|
98
|
+
[`${ctx.names.kebab}.service.ts`, renderService(ctx)],
|
|
99
|
+
[`${ctx.names.kebab}.dto.ts`, renderDto(ctx)],
|
|
100
|
+
[`${ctx.names.kebab}.validator.ts`, renderValidator(ctx)],
|
|
101
|
+
[`${ctx.names.kebab}.routes.ts`, renderRoutes(ctx)],
|
|
102
|
+
];
|
|
103
|
+
const written = [];
|
|
104
|
+
for (const [fileName, content] of files) {
|
|
105
|
+
const filePath = (0, path_1.join)(targetDir, fileName);
|
|
106
|
+
if ((0, fs_1.existsSync)(filePath)) {
|
|
107
|
+
throw new Error(`File already exists: ${filePath}`);
|
|
108
|
+
}
|
|
109
|
+
(0, fs_1.writeFileSync)(filePath, content, "utf-8");
|
|
110
|
+
written.push(filePath);
|
|
111
|
+
}
|
|
112
|
+
return written;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/templates/module.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAclD;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
exports.getDefaultConfigContent = getDefaultConfigContent;
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
apiDir: "src/api",
|
|
9
|
+
indexFile: "src/index.ts",
|
|
10
|
+
routePrefix: "/api",
|
|
11
|
+
};
|
|
12
|
+
function loadConfig(cwd) {
|
|
13
|
+
const configPath = (0, path_1.join)(cwd, ".bogorc.json");
|
|
14
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
15
|
+
return DEFAULT_CONFIG;
|
|
16
|
+
}
|
|
17
|
+
const raw = (0, fs_1.readFileSync)(configPath, "utf-8");
|
|
18
|
+
const parsed = JSON.parse(raw);
|
|
19
|
+
return {
|
|
20
|
+
...DEFAULT_CONFIG,
|
|
21
|
+
...parsed,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function getDefaultConfigContent() {
|
|
25
|
+
return `${JSON.stringify(DEFAULT_CONFIG, null, 2)}\n`;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":";;AAUA,gCAcC;AAED,0DAEC;AA5BD,2BAA8C;AAC9C,+BAA4B;AAG5B,MAAM,cAAc,GAAe;IACjC,MAAM,EAAE,SAAS;IACjB,SAAS,EAAE,cAAc;IACzB,WAAW,EAAE,MAAM;CACpB,CAAC;AAEF,SAAgB,UAAU,CAAC,GAAW;IACpC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAE7C,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;IAEtD,OAAO;QACL,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,SAAgB,uBAAuB;IACrC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ModuleNames } from "../interfaces";
|
|
2
|
+
export declare function toKebabCase(value: string): string;
|
|
3
|
+
export declare function toPascalCase(value: string): string;
|
|
4
|
+
export declare function toCamelCase(value: string): string;
|
|
5
|
+
export declare function normalizeModuleName(name: string): string;
|
|
6
|
+
export declare function resolveModuleNames(name: string): ModuleNames;
|
|
7
|
+
export declare function methodToRoutePath(method: string, customPath?: string): string;
|
|
8
|
+
//# sourceMappingURL=naming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAO5D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7E"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toKebabCase = toKebabCase;
|
|
4
|
+
exports.toPascalCase = toPascalCase;
|
|
5
|
+
exports.toCamelCase = toCamelCase;
|
|
6
|
+
exports.normalizeModuleName = normalizeModuleName;
|
|
7
|
+
exports.resolveModuleNames = resolveModuleNames;
|
|
8
|
+
exports.methodToRoutePath = methodToRoutePath;
|
|
9
|
+
function toKebabCase(value) {
|
|
10
|
+
return value
|
|
11
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
12
|
+
.replace(/[\s_]+/g, "-")
|
|
13
|
+
.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
function toPascalCase(value) {
|
|
16
|
+
return value
|
|
17
|
+
.split(/[-_\s]+/)
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
|
|
20
|
+
.join("");
|
|
21
|
+
}
|
|
22
|
+
function toCamelCase(value) {
|
|
23
|
+
const pascal = toPascalCase(value);
|
|
24
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
25
|
+
}
|
|
26
|
+
function normalizeModuleName(name) {
|
|
27
|
+
return toKebabCase(name.replace(/Controller$|Service$|Routes$|Dto$|Validator$/i, ""));
|
|
28
|
+
}
|
|
29
|
+
function resolveModuleNames(name) {
|
|
30
|
+
const kebab = normalizeModuleName(name);
|
|
31
|
+
return {
|
|
32
|
+
kebab,
|
|
33
|
+
pascal: toPascalCase(kebab),
|
|
34
|
+
camel: toCamelCase(kebab),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function methodToRoutePath(method, customPath) {
|
|
38
|
+
if (customPath) {
|
|
39
|
+
return customPath.startsWith("/") ? customPath : `/${customPath}`;
|
|
40
|
+
}
|
|
41
|
+
return `/${toKebabCase(method)}`;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/utils/naming.ts"],"names":[],"mappings":";;AAEA,kCAKC;AAED,oCAMC;AAED,kCAGC;AAED,kDAEC;AAED,gDAOC;AAED,8CAKC;AAtCD,SAAgB,WAAW,CAAC,KAAa;IACvC,OAAO,KAAK;SACT,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAO,KAAK;SACT,KAAK,CAAC,SAAS,CAAC;SAChB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SACvE,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,OAAO,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,+CAA+C,EAAE,EAAE,CAAC,CAAC,CAAC;AACxF,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO;QACL,KAAK;QACL,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;QAC3B,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,SAAgB,iBAAiB,CAAC,MAAc,EAAE,UAAmB;IACnE,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;IACpE,CAAC;IACD,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ModuleNames } from "../interfaces";
|
|
2
|
+
export declare function patchIndexFile(indexPath: string, names: ModuleNames, routePrefix: string): boolean;
|
|
3
|
+
export declare function suggestIndexPatch(names: ModuleNames, routePrefix: string): string;
|
|
4
|
+
//# sourceMappingURL=patch-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-index.d.ts","sourceRoot":"","sources":["../../src/utils/patch-index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAiDlG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAKjF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.patchIndexFile = patchIndexFile;
|
|
4
|
+
exports.suggestIndexPatch = suggestIndexPatch;
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
function patchIndexFile(indexPath, names, routePrefix) {
|
|
7
|
+
if (!(0, fs_1.existsSync)(indexPath)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const importLine = `import ${names.pascal}Routes from "./api/${names.kebab}/${names.kebab}.routes";`;
|
|
11
|
+
const useLine = `app.use("${routePrefix}/${names.kebab}", ${names.pascal}Routes);`;
|
|
12
|
+
let content = (0, fs_1.readFileSync)(indexPath, "utf-8");
|
|
13
|
+
if (content.includes(importLine) || content.includes(useLine)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const importAnchor = content.match(/^import .+ from .+;$/m);
|
|
17
|
+
if (importAnchor && importAnchor.index !== undefined) {
|
|
18
|
+
const lines = content.split("\n");
|
|
19
|
+
let lastImportIndex = -1;
|
|
20
|
+
for (let i = 0; i < lines.length; i++) {
|
|
21
|
+
if (/^import .+ from .+;$/.test(lines[i])) {
|
|
22
|
+
lastImportIndex = i;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (lastImportIndex >= 0) {
|
|
26
|
+
lines.splice(lastImportIndex + 1, 0, importLine);
|
|
27
|
+
content = lines.join("\n");
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
content = `${importLine}\n${content}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
content = `${importLine}\n${content}`;
|
|
35
|
+
}
|
|
36
|
+
const useAnchor = content.match(/app\.use\("\/api\/.+", .+Routes\);/);
|
|
37
|
+
if (useAnchor && useAnchor.index !== undefined) {
|
|
38
|
+
content = content.replace(useAnchor[0], `${useAnchor[0]}\n${useLine}`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const listenAnchor = content.match(/app\.listen\(/);
|
|
42
|
+
if (listenAnchor && listenAnchor.index !== undefined) {
|
|
43
|
+
content = content.replace(listenAnchor[0], `${useLine}\n\n${listenAnchor[0]}`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
content = `${content.trimEnd()}\n${useLine}\n`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
(0, fs_1.writeFileSync)(indexPath, content, "utf-8");
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
function suggestIndexPatch(names, routePrefix) {
|
|
53
|
+
return `Add to index manually:
|
|
54
|
+
|
|
55
|
+
import ${names.pascal}Routes from "./api/${names.kebab}/${names.kebab}.routes";
|
|
56
|
+
app.use("${routePrefix}/${names.kebab}", ${names.pascal}Routes);`;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=patch-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-index.js","sourceRoot":"","sources":["../../src/utils/patch-index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bogomolcompany/bogo",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"description": "CLI generator for Express API modules",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"bin": {
|
|
10
|
+
"bogo": "./dist/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/cli.js",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "ts-node src/cli.ts",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"commander": "^12.1.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^22.5.0",
|
|
26
|
+
"ts-node": "^10.9.2",
|
|
27
|
+
"typescript": "^5.5.4"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
}
|
|
32
|
+
}
|