@gaman/kame 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 +21 -0
- package/dist/commands/buntest-cmd.d.ts +1 -0
- package/dist/commands/buntest-cmd.js +23 -0
- package/dist/commands/buntest-cmd.mjs +24 -0
- package/dist/commands/fetch.d.ts +1 -0
- package/dist/commands/fetch.js +46 -0
- package/dist/commands/fetch.mjs +46 -0
- package/dist/commands/gen-controller.d.ts +1 -0
- package/dist/commands/gen-controller.js +21 -0
- package/dist/commands/gen-controller.mjs +24 -0
- package/dist/commands/gen-exception.d.ts +1 -0
- package/dist/commands/gen-exception.js +23 -0
- package/dist/commands/gen-exception.mjs +26 -0
- package/dist/commands/gen-middleware.d.ts +1 -0
- package/dist/commands/gen-middleware.js +23 -0
- package/dist/commands/gen-middleware.mjs +26 -0
- package/dist/commands/gen-module.d.ts +1 -0
- package/dist/commands/gen-module.js +40 -0
- package/dist/commands/gen-module.mjs +47 -0
- package/dist/commands/gen-router.d.ts +1 -0
- package/dist/commands/gen-router.js +19 -0
- package/dist/commands/gen-router.mjs +22 -0
- package/dist/commands/gen-service.d.ts +1 -0
- package/dist/commands/gen-service.js +55 -0
- package/dist/commands/gen-service.mjs +58 -0
- package/dist/commands/registry.d.ts +26 -0
- package/dist/commands/registry.js +75 -0
- package/dist/commands/registry.mjs +51 -0
- package/dist/compose/index.d.ts +5 -0
- package/dist/compose/index.js +33 -0
- package/dist/compose/index.mjs +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +30 -0
- package/dist/index.mjs +10 -0
- package/dist/input-parser.d.ts +5 -0
- package/dist/input-parser.js +40 -0
- package/dist/input-parser.mjs +19 -0
- package/dist/repl.d.ts +9 -0
- package/dist/repl.js +63 -0
- package/dist/repl.mjs +45 -0
- package/dist/templates/module.d.ts +6 -0
- package/dist/templates/module.js +123 -0
- package/dist/templates/module.mjs +97 -0
- package/dist/templates/service.d.ts +1 -0
- package/dist/templates/service.js +41 -0
- package/dist/templates/service.mjs +20 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +27 -0
- package/dist/utils.mjs +5 -0
- package/package.json +41 -0
- package/tsconfig.dts.json +60 -0
- package/tsconfig.json +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @gaman/static
|
|
2
|
+
**Secure, Lightweight & High-Performance Static File Server for GamanJS**. Built for Bun, optimized for speed with non-blocking I/O, built-in compression, and ETag caching.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
```bash
|
|
6
|
+
bun add @gaman/static
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Quick Used
|
|
10
|
+
By default, this middleware will serve files from the `public/` folder in the root of your project.
|
|
11
|
+
```ts
|
|
12
|
+
import { defineBootstrap } from "gaman";
|
|
13
|
+
import { StaticServe } from "@gaman/static";
|
|
14
|
+
|
|
15
|
+
defineBootstrap((app) => {
|
|
16
|
+
// Mount the static server
|
|
17
|
+
app.mount(StaticServe());
|
|
18
|
+
|
|
19
|
+
app.mountServer(...)
|
|
20
|
+
});
|
|
21
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_bun = require("bun"), import_utils = require('gaman/utils'), import_registry = require('./registry.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
import_utils.Logger.info("Starting Bun test suite...");
|
|
5
|
+
try {
|
|
6
|
+
(await import_bun.$`bun test ${args}`.quiet().text()).split(`
|
|
7
|
+
`).forEach((line) => {
|
|
8
|
+
line.trim() && import_utils.Logger.info(line);
|
|
9
|
+
}), import_utils.Logger.info("All tests passed successfully.");
|
|
10
|
+
} catch (err) {
|
|
11
|
+
(err.stderr?.toString() || err.stdout?.toString() || "").split(`
|
|
12
|
+
`).forEach((line) => {
|
|
13
|
+
line.trim() && import_utils.Logger.error(line);
|
|
14
|
+
}), import_utils.Logger.error("Test suite failed.");
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
(0, import_registry.registerCommand)({
|
|
18
|
+
name: "test",
|
|
19
|
+
description: "Run project tests.",
|
|
20
|
+
usage: "test [filter]",
|
|
21
|
+
aliases: ["t"],
|
|
22
|
+
handler
|
|
23
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { $ } from "bun";
|
|
2
|
+
import { Logger } from 'gaman/utils';
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
const handler = async (args) => {
|
|
5
|
+
Logger.info("Starting Bun test suite...");
|
|
6
|
+
try {
|
|
7
|
+
(await $`bun test ${args}`.quiet().text()).split(`
|
|
8
|
+
`).forEach((line) => {
|
|
9
|
+
line.trim() && Logger.info(line);
|
|
10
|
+
}), Logger.info("All tests passed successfully.");
|
|
11
|
+
} catch (err) {
|
|
12
|
+
(err.stderr?.toString() || err.stdout?.toString() || "").split(`
|
|
13
|
+
`).forEach((line) => {
|
|
14
|
+
line.trim() && Logger.error(line);
|
|
15
|
+
}), Logger.error("Test suite failed.");
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
registerCommand({
|
|
19
|
+
name: "test",
|
|
20
|
+
description: "Run project tests.",
|
|
21
|
+
usage: "test [filter]",
|
|
22
|
+
aliases: ["t"],
|
|
23
|
+
handler
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_registry = require('./registry.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const method = args[0]?.toUpperCase(), url = args[1];
|
|
5
|
+
if (!method || !url) {
|
|
6
|
+
import_utils.Logger.error("Usage: fetch <METHOD> <URL> [-h Header] [-b Body]");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const headerIndex = args.indexOf("-h"), bodyIndex = args.indexOf("-b"), headers = {
|
|
10
|
+
"Content-Type": "application/json"
|
|
11
|
+
};
|
|
12
|
+
if (headerIndex !== -1 && args[headerIndex + 1]) {
|
|
13
|
+
const headerRaw = args[headerIndex + 1], splitIndex = headerRaw?.indexOf(":") || -1;
|
|
14
|
+
if (splitIndex !== -1) {
|
|
15
|
+
const key = headerRaw?.slice(0, splitIndex).trim() || "", value = headerRaw?.slice(splitIndex + 1).trim() || "";
|
|
16
|
+
headers[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let body = null;
|
|
20
|
+
bodyIndex !== -1 && args[bodyIndex + 1] && (body = args[bodyIndex + 1]), import_utils.Logger.info(`Sending ${method} request to: ${url}`);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
method,
|
|
24
|
+
headers,
|
|
25
|
+
body: ["GET", "HEAD"].includes(method) ? null : body
|
|
26
|
+
}), resText = await response.text();
|
|
27
|
+
let resData;
|
|
28
|
+
try {
|
|
29
|
+
resData = JSON.parse(resText);
|
|
30
|
+
} catch {
|
|
31
|
+
resData = resText;
|
|
32
|
+
}
|
|
33
|
+
response.ok ? (import_utils.Logger.info(`Status: ${response.status}`), console.log(
|
|
34
|
+
typeof resData == "object" ? JSON.stringify(resData, null, 2) : resData
|
|
35
|
+
)) : (import_utils.Logger.error(`Status: ${response.status}`), console.log(resData));
|
|
36
|
+
} catch (err) {
|
|
37
|
+
import_utils.Logger.error(`Fetch failed: ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
(0, import_registry.registerCommand)({
|
|
41
|
+
name: "fetch",
|
|
42
|
+
description: "Request internal/external API via CLI",
|
|
43
|
+
usage: 'fetch <METHOD> <URL> [-h "Key: Value"] [-b "Body"]',
|
|
44
|
+
aliases: ["req"],
|
|
45
|
+
handler
|
|
46
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Logger } from 'gaman/utils';
|
|
2
|
+
import { registerCommand } from "./registry.mjs";
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const method = args[0]?.toUpperCase(), url = args[1];
|
|
5
|
+
if (!method || !url) {
|
|
6
|
+
Logger.error("Usage: fetch <METHOD> <URL> [-h Header] [-b Body]");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const headerIndex = args.indexOf("-h"), bodyIndex = args.indexOf("-b"), headers = {
|
|
10
|
+
"Content-Type": "application/json"
|
|
11
|
+
};
|
|
12
|
+
if (headerIndex !== -1 && args[headerIndex + 1]) {
|
|
13
|
+
const headerRaw = args[headerIndex + 1], splitIndex = headerRaw?.indexOf(":") || -1;
|
|
14
|
+
if (splitIndex !== -1) {
|
|
15
|
+
const key = headerRaw?.slice(0, splitIndex).trim() || "", value = headerRaw?.slice(splitIndex + 1).trim() || "";
|
|
16
|
+
headers[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let body = null;
|
|
20
|
+
bodyIndex !== -1 && args[bodyIndex + 1] && (body = args[bodyIndex + 1]), Logger.info(`Sending ${method} request to: ${url}`);
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
method,
|
|
24
|
+
headers,
|
|
25
|
+
body: ["GET", "HEAD"].includes(method) ? null : body
|
|
26
|
+
}), resText = await response.text();
|
|
27
|
+
let resData;
|
|
28
|
+
try {
|
|
29
|
+
resData = JSON.parse(resText);
|
|
30
|
+
} catch {
|
|
31
|
+
resData = resText;
|
|
32
|
+
}
|
|
33
|
+
response.ok ? (Logger.info(`Status: ${response.status}`), console.log(
|
|
34
|
+
typeof resData == "object" ? JSON.stringify(resData, null, 2) : resData
|
|
35
|
+
)) : (Logger.error(`Status: ${response.status}`), console.log(resData));
|
|
36
|
+
} catch (err) {
|
|
37
|
+
Logger.error(`Fetch failed: ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
registerCommand({
|
|
41
|
+
name: "fetch",
|
|
42
|
+
description: "Request internal/external API via CLI",
|
|
43
|
+
usage: 'fetch <METHOD> <URL> [-h "Key: Value"] [-b "Body"]',
|
|
44
|
+
aliases: ["req"],
|
|
45
|
+
handler
|
|
46
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_module = require('../templates/module.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const [name, module2 = "app"] = args;
|
|
5
|
+
if (!name || !module2) {
|
|
6
|
+
import_utils.Logger.error("Usage: gen:controller <name> <module: 'app'>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nameCapitalized = (0, import_utils2.capitalize)(name), cwd = process.cwd(), controllerDir = (0, import_node_path.join)(cwd, "src", "modules", module2, "controllers"), filePath = (0, import_node_path.join)(controllerDir, `${nameCapitalized}Controller.ts`);
|
|
10
|
+
await Bun.$`mkdir -p ${controllerDir}`.quiet(), await Bun.write(filePath, (0, import_module.controllerTemplate)(name) + `
|
|
11
|
+
`), import_utils.Logger.info(`created ${(0, import_node_path.relative)(cwd, filePath)}`), import_utils.Logger.info(
|
|
12
|
+
`Controller "${nameCapitalized}Controller" generated successfully.`
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
(0, import_registry.registerCommand)({
|
|
16
|
+
name: "gen:controller",
|
|
17
|
+
description: "Generate a new Controller inside an existing module",
|
|
18
|
+
usage: "gen:controller <name> <module: 'app'>",
|
|
19
|
+
aliases: ["gen:co"],
|
|
20
|
+
handler
|
|
21
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Logger } from 'gaman/utils';
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import { controllerTemplate } from "../templates/module.mjs";
|
|
5
|
+
import { capitalize } from "../utils.mjs";
|
|
6
|
+
const handler = async (args) => {
|
|
7
|
+
const [name, module = "app"] = args;
|
|
8
|
+
if (!name || !module) {
|
|
9
|
+
Logger.error("Usage: gen:controller <name> <module: 'app'>");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nameCapitalized = capitalize(name), cwd = process.cwd(), controllerDir = join(cwd, "src", "modules", module, "controllers"), filePath = join(controllerDir, `${nameCapitalized}Controller.ts`);
|
|
13
|
+
await Bun.$`mkdir -p ${controllerDir}`.quiet(), await Bun.write(filePath, controllerTemplate(name) + `
|
|
14
|
+
`), Logger.info(`created ${relative(cwd, filePath)}`), Logger.info(
|
|
15
|
+
`Controller "${nameCapitalized}Controller" generated successfully.`
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
registerCommand({
|
|
19
|
+
name: "gen:controller",
|
|
20
|
+
description: "Generate a new Controller inside an existing module",
|
|
21
|
+
usage: "gen:controller <name> <module: 'app'>",
|
|
22
|
+
aliases: ["gen:co"],
|
|
23
|
+
handler
|
|
24
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_module = require('../templates/module.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const [name, module2 = "app"] = args;
|
|
5
|
+
if (!name || !module2) {
|
|
6
|
+
import_utils.Logger.error("Usage: gen:exception <name> <module: 'app'>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nameCapitalized = (0, import_utils2.capitalize)(name), cwd = process.cwd(), exceptionDir = (0, import_node_path.join)(cwd, "src", "modules", module2, "exceptions"), filePath = (0, import_node_path.join)(exceptionDir, `${nameCapitalized}Exception.ts`);
|
|
10
|
+
await Bun.$`mkdir -p ${exceptionDir}`.quiet(), await Bun.write(filePath, (0, import_module.exceptionTemplate)() + `
|
|
11
|
+
`), import_utils.Logger.info(
|
|
12
|
+
`created ${import_utils.TextFormat.UNDERLINE}${(0, import_node_path.relative)(cwd, filePath)}${import_utils.TextFormat.RESET}`
|
|
13
|
+
), import_utils.Logger.info(
|
|
14
|
+
`Exception "${nameCapitalized}Exception" generated successfully.`
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
(0, import_registry.registerCommand)({
|
|
18
|
+
name: "gen:exception",
|
|
19
|
+
description: "Generate a new Exception inside an existing module",
|
|
20
|
+
usage: "gen:exception <name> <module: 'app'>",
|
|
21
|
+
aliases: ["gen:ex"],
|
|
22
|
+
handler
|
|
23
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Logger, TextFormat } from 'gaman/utils';
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import { exceptionTemplate } from "../templates/module.mjs";
|
|
5
|
+
import { capitalize } from "../utils.mjs";
|
|
6
|
+
const handler = async (args) => {
|
|
7
|
+
const [name, module = "app"] = args;
|
|
8
|
+
if (!name || !module) {
|
|
9
|
+
Logger.error("Usage: gen:exception <name> <module: 'app'>");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nameCapitalized = capitalize(name), cwd = process.cwd(), exceptionDir = join(cwd, "src", "modules", module, "exceptions"), filePath = join(exceptionDir, `${nameCapitalized}Exception.ts`);
|
|
13
|
+
await Bun.$`mkdir -p ${exceptionDir}`.quiet(), await Bun.write(filePath, exceptionTemplate() + `
|
|
14
|
+
`), Logger.info(
|
|
15
|
+
`created ${TextFormat.UNDERLINE}${relative(cwd, filePath)}${TextFormat.RESET}`
|
|
16
|
+
), Logger.info(
|
|
17
|
+
`Exception "${nameCapitalized}Exception" generated successfully.`
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
registerCommand({
|
|
21
|
+
name: "gen:exception",
|
|
22
|
+
description: "Generate a new Exception inside an existing module",
|
|
23
|
+
usage: "gen:exception <name> <module: 'app'>",
|
|
24
|
+
aliases: ["gen:ex"],
|
|
25
|
+
handler
|
|
26
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_module = require('../templates/module.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const [name, module2 = "app"] = args;
|
|
5
|
+
if (!name || !module2) {
|
|
6
|
+
import_utils.Logger.error("Usage: gen:middleware <name> <module: 'app'>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nameCapitalized = (0, import_utils2.capitalize)(name), cwd = process.cwd(), middlewareDir = (0, import_node_path.join)(cwd, "src", "modules", module2, "middlewares"), filePath = (0, import_node_path.join)(middlewareDir, `${nameCapitalized}Middleware.ts`);
|
|
10
|
+
await Bun.$`mkdir -p ${middlewareDir}`.quiet(), await Bun.write(filePath, (0, import_module.middlewareTemplate)() + `
|
|
11
|
+
`), import_utils.Logger.info(
|
|
12
|
+
`created ${import_utils.TextFormat.UNDERLINE}${(0, import_node_path.relative)(cwd, filePath)}${import_utils.TextFormat.RESET}`
|
|
13
|
+
), import_utils.Logger.info(
|
|
14
|
+
`Middleware "${nameCapitalized}Middleware" generated successfully.`
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
(0, import_registry.registerCommand)({
|
|
18
|
+
name: "gen:middleware",
|
|
19
|
+
description: "Generate a new Middleware inside an existing module",
|
|
20
|
+
usage: "gen:middleware <name> <module: 'app'>",
|
|
21
|
+
aliases: ["gen:mi"],
|
|
22
|
+
handler
|
|
23
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Logger, TextFormat } from 'gaman/utils';
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import { middlewareTemplate } from "../templates/module.mjs";
|
|
5
|
+
import { capitalize } from "../utils.mjs";
|
|
6
|
+
const handler = async (args) => {
|
|
7
|
+
const [name, module = "app"] = args;
|
|
8
|
+
if (!name || !module) {
|
|
9
|
+
Logger.error("Usage: gen:middleware <name> <module: 'app'>");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nameCapitalized = capitalize(name), cwd = process.cwd(), middlewareDir = join(cwd, "src", "modules", module, "middlewares"), filePath = join(middlewareDir, `${nameCapitalized}Middleware.ts`);
|
|
13
|
+
await Bun.$`mkdir -p ${middlewareDir}`.quiet(), await Bun.write(filePath, middlewareTemplate() + `
|
|
14
|
+
`), Logger.info(
|
|
15
|
+
`created ${TextFormat.UNDERLINE}${relative(cwd, filePath)}${TextFormat.RESET}`
|
|
16
|
+
), Logger.info(
|
|
17
|
+
`Middleware "${nameCapitalized}Middleware" generated successfully.`
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
registerCommand({
|
|
21
|
+
name: "gen:middleware",
|
|
22
|
+
description: "Generate a new Middleware inside an existing module",
|
|
23
|
+
usage: "gen:middleware <name> <module: 'app'>",
|
|
24
|
+
aliases: ["gen:mi"],
|
|
25
|
+
handler
|
|
26
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_module = require('../templates/module.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const modulePath = args[0];
|
|
5
|
+
if (!modulePath) {
|
|
6
|
+
import_utils.Logger.error("Usage: gen:module <name>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const name = (0, import_node_path.basename)(modulePath), nameCapitalized = (0, import_utils2.capitalize)(name), cwd = process.cwd(), moduleDir = (0, import_node_path.join)(cwd, "src", "modules", modulePath), files = [
|
|
10
|
+
{
|
|
11
|
+
filePath: (0, import_node_path.join)(
|
|
12
|
+
moduleDir,
|
|
13
|
+
"controllers",
|
|
14
|
+
`${nameCapitalized}Controller.ts`
|
|
15
|
+
),
|
|
16
|
+
content: (0, import_module.controllerTemplate)(name)
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
filePath: (0, import_node_path.join)(moduleDir, "services", `${nameCapitalized}Service.ts`),
|
|
20
|
+
content: (0, import_module.serviceTemplate)(name)
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
filePath: (0, import_node_path.join)(moduleDir, `${nameCapitalized}Router.ts`),
|
|
24
|
+
content: (0, import_module.routerTemplate)(name)
|
|
25
|
+
}
|
|
26
|
+
];
|
|
27
|
+
for (const { filePath, content } of files) {
|
|
28
|
+
const dir = (0, import_node_path.dirname)(filePath);
|
|
29
|
+
await Bun.$`mkdir -p ${dir}`.quiet(), await Bun.write(filePath, content + `
|
|
30
|
+
`), import_utils.Logger.info(`created ${(0, import_node_path.relative)(cwd, filePath)}`);
|
|
31
|
+
}
|
|
32
|
+
import_utils.Logger.info(`Module "${nameCapitalized}" generated successfully.`);
|
|
33
|
+
};
|
|
34
|
+
(0, import_registry.registerCommand)({
|
|
35
|
+
name: "gen:module",
|
|
36
|
+
description: "Generate a new module with Controller, Service, and Router",
|
|
37
|
+
usage: "gen:module <name>",
|
|
38
|
+
aliases: ["gen:mo"],
|
|
39
|
+
handler
|
|
40
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Logger } from 'gaman/utils';
|
|
2
|
+
import { join, basename, relative, dirname } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import {
|
|
5
|
+
controllerTemplate,
|
|
6
|
+
routerTemplate,
|
|
7
|
+
serviceTemplate
|
|
8
|
+
} from "../templates/module.mjs";
|
|
9
|
+
import { capitalize } from "../utils.mjs";
|
|
10
|
+
const handler = async (args) => {
|
|
11
|
+
const modulePath = args[0];
|
|
12
|
+
if (!modulePath) {
|
|
13
|
+
Logger.error("Usage: gen:module <name>");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const name = basename(modulePath), nameCapitalized = capitalize(name), cwd = process.cwd(), moduleDir = join(cwd, "src", "modules", modulePath), files = [
|
|
17
|
+
{
|
|
18
|
+
filePath: join(
|
|
19
|
+
moduleDir,
|
|
20
|
+
"controllers",
|
|
21
|
+
`${nameCapitalized}Controller.ts`
|
|
22
|
+
),
|
|
23
|
+
content: controllerTemplate(name)
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
filePath: join(moduleDir, "services", `${nameCapitalized}Service.ts`),
|
|
27
|
+
content: serviceTemplate(name)
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
filePath: join(moduleDir, `${nameCapitalized}Router.ts`),
|
|
31
|
+
content: routerTemplate(name)
|
|
32
|
+
}
|
|
33
|
+
];
|
|
34
|
+
for (const { filePath, content } of files) {
|
|
35
|
+
const dir = dirname(filePath);
|
|
36
|
+
await Bun.$`mkdir -p ${dir}`.quiet(), await Bun.write(filePath, content + `
|
|
37
|
+
`), Logger.info(`created ${relative(cwd, filePath)}`);
|
|
38
|
+
}
|
|
39
|
+
Logger.info(`Module "${nameCapitalized}" generated successfully.`);
|
|
40
|
+
};
|
|
41
|
+
registerCommand({
|
|
42
|
+
name: "gen:module",
|
|
43
|
+
description: "Generate a new module with Controller, Service, and Router",
|
|
44
|
+
usage: "gen:module <name>",
|
|
45
|
+
aliases: ["gen:mo"],
|
|
46
|
+
handler
|
|
47
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_module = require('../templates/module.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const handler = async (args) => {
|
|
4
|
+
const [name, module2 = "app"] = args;
|
|
5
|
+
if (!name || !module2) {
|
|
6
|
+
import_utils.Logger.error("Usage: gen:router <name> <module: 'app'>");
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nameCapitalized = (0, import_utils2.capitalize)(name), cwd = process.cwd(), routerDir = (0, import_node_path.join)(cwd, "src", "modules", module2), filePath = (0, import_node_path.join)(routerDir, `${nameCapitalized}Router.ts`);
|
|
10
|
+
await Bun.$`mkdir -p ${routerDir}`.quiet(), await Bun.write(filePath, (0, import_module.routerBlankTemplate)() + `
|
|
11
|
+
`), import_utils.Logger.info(`created ${(0, import_node_path.relative)(cwd, filePath)}`), import_utils.Logger.info(`Router "${nameCapitalized}Router" generated successfully.`);
|
|
12
|
+
};
|
|
13
|
+
(0, import_registry.registerCommand)({
|
|
14
|
+
name: "gen:router",
|
|
15
|
+
description: "Generate a new Router inside an existing module",
|
|
16
|
+
usage: "gen:router <name> <module: 'app'>",
|
|
17
|
+
aliases: ["gen:ro"],
|
|
18
|
+
handler
|
|
19
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Logger } from 'gaman/utils';
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import { routerBlankTemplate } from "../templates/module.mjs";
|
|
5
|
+
import { capitalize } from "../utils.mjs";
|
|
6
|
+
const handler = async (args) => {
|
|
7
|
+
const [name, module = "app"] = args;
|
|
8
|
+
if (!name || !module) {
|
|
9
|
+
Logger.error("Usage: gen:router <name> <module: 'app'>");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nameCapitalized = capitalize(name), cwd = process.cwd(), routerDir = join(cwd, "src", "modules", module), filePath = join(routerDir, `${nameCapitalized}Router.ts`);
|
|
13
|
+
await Bun.$`mkdir -p ${routerDir}`.quiet(), await Bun.write(filePath, routerBlankTemplate() + `
|
|
14
|
+
`), Logger.info(`created ${relative(cwd, filePath)}`), Logger.info(`Router "${nameCapitalized}Router" generated successfully.`);
|
|
15
|
+
};
|
|
16
|
+
registerCommand({
|
|
17
|
+
name: "gen:router",
|
|
18
|
+
description: "Generate a new Router inside an existing module",
|
|
19
|
+
usage: "gen:router <name> <module: 'app'>",
|
|
20
|
+
aliases: ["gen:ro"],
|
|
21
|
+
handler
|
|
22
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_utils = require('gaman/utils'), import_node_path = require("node:path"), import_registry = require('./registry.js'), import_service = require('../templates/service.js'), import_utils2 = require('../utils.js');
|
|
3
|
+
const patchRouter = async (routerPath, serviceName) => {
|
|
4
|
+
const file = Bun.file(routerPath);
|
|
5
|
+
if (!await file.exists()) {
|
|
6
|
+
import_utils.Logger.warn(`Router not found at ${routerPath}, skipping auto-register.`);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const nameCapitalized = (0, import_utils2.capitalize)(serviceName), camelName = (0, import_utils2.toCamelCase)(serviceName), importLine = `import { ${nameCapitalized}Service } from './services/${nameCapitalized}Service';`, mountEntry = ` ${camelName}Service: ${nameCapitalized}Service(),`;
|
|
10
|
+
let source = await file.text();
|
|
11
|
+
if (!source.includes(importLine)) {
|
|
12
|
+
const lastImportIdx = source.lastIndexOf(`
|
|
13
|
+
import `), insertAfter = lastImportIdx !== -1 ? source.indexOf(`
|
|
14
|
+
`, lastImportIdx + 1) : source.indexOf(`
|
|
15
|
+
`);
|
|
16
|
+
source = source.slice(0, insertAfter) + `
|
|
17
|
+
` + importLine + source.slice(insertAfter);
|
|
18
|
+
}
|
|
19
|
+
if (!source.includes(`${camelName}Service:`)) {
|
|
20
|
+
const mountStart = source.indexOf("r.mountService({");
|
|
21
|
+
if (mountStart !== -1) {
|
|
22
|
+
const closingIdx = source.indexOf(" });", mountStart);
|
|
23
|
+
closingIdx !== -1 && (source = source.slice(0, closingIdx) + mountEntry + `
|
|
24
|
+
` + source.slice(closingIdx));
|
|
25
|
+
} else
|
|
26
|
+
import_utils.Logger.warn(
|
|
27
|
+
`r.mountService block not found in ${routerPath}, skipping auto-register.`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
await Bun.write(routerPath, source);
|
|
31
|
+
}, handler = async (args) => {
|
|
32
|
+
const [name, module2 = "app"] = args;
|
|
33
|
+
if (!name || !module2) {
|
|
34
|
+
import_utils.Logger.error("Usage: gen:service <name> <module: 'app'>");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const nameCapitalized = (0, import_utils2.capitalize)(name), moduleSegment = (0, import_node_path.basename)(module2), moduleCapitalized = (0, import_utils2.capitalize)(moduleSegment), cwd = process.cwd(), serviceDir = (0, import_node_path.join)(cwd, "src", "modules", module2, "services"), filePath = (0, import_node_path.join)(serviceDir, `${nameCapitalized}Service.ts`);
|
|
38
|
+
await Bun.$`mkdir -p ${serviceDir}`.quiet(), await Bun.write(filePath, (0, import_service.standaloneServiceTemplate)(name) + `
|
|
39
|
+
`), import_utils.Logger.info(`created ${(0, import_node_path.relative)(cwd, filePath)}`);
|
|
40
|
+
const routerPath = (0, import_node_path.join)(
|
|
41
|
+
cwd,
|
|
42
|
+
"src",
|
|
43
|
+
"modules",
|
|
44
|
+
module2,
|
|
45
|
+
`${moduleCapitalized}Router.ts`
|
|
46
|
+
);
|
|
47
|
+
await patchRouter(routerPath, name), import_utils.Logger.info(`updated ${(0, import_node_path.relative)(cwd, routerPath)}`), import_utils.Logger.info(`Service "${nameCapitalized}Service" generated successfully.`);
|
|
48
|
+
};
|
|
49
|
+
(0, import_registry.registerCommand)({
|
|
50
|
+
name: "gen:service",
|
|
51
|
+
description: "Generate a new Service and register it in the module Router",
|
|
52
|
+
usage: "gen:service <name> <module: 'app'>",
|
|
53
|
+
aliases: ["gen:se"],
|
|
54
|
+
handler
|
|
55
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Logger } from 'gaman/utils';
|
|
2
|
+
import { join, relative, basename } from "node:path";
|
|
3
|
+
import { registerCommand } from "./registry.mjs";
|
|
4
|
+
import { standaloneServiceTemplate } from "../templates/service.mjs";
|
|
5
|
+
import { capitalize, toCamelCase } from "../utils.mjs";
|
|
6
|
+
const patchRouter = async (routerPath, serviceName) => {
|
|
7
|
+
const file = Bun.file(routerPath);
|
|
8
|
+
if (!await file.exists()) {
|
|
9
|
+
Logger.warn(`Router not found at ${routerPath}, skipping auto-register.`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const nameCapitalized = capitalize(serviceName), camelName = toCamelCase(serviceName), importLine = `import { ${nameCapitalized}Service } from './services/${nameCapitalized}Service.mjs';`, mountEntry = ` ${camelName}Service: ${nameCapitalized}Service(),`;
|
|
13
|
+
let source = await file.text();
|
|
14
|
+
if (!source.includes(importLine)) {
|
|
15
|
+
const lastImportIdx = source.lastIndexOf(`
|
|
16
|
+
import `), insertAfter = lastImportIdx !== -1 ? source.indexOf(`
|
|
17
|
+
`, lastImportIdx + 1) : source.indexOf(`
|
|
18
|
+
`);
|
|
19
|
+
source = source.slice(0, insertAfter) + `
|
|
20
|
+
` + importLine + source.slice(insertAfter);
|
|
21
|
+
}
|
|
22
|
+
if (!source.includes(`${camelName}Service:`)) {
|
|
23
|
+
const mountStart = source.indexOf("r.mountService({");
|
|
24
|
+
if (mountStart !== -1) {
|
|
25
|
+
const closingIdx = source.indexOf(" });", mountStart);
|
|
26
|
+
closingIdx !== -1 && (source = source.slice(0, closingIdx) + mountEntry + `
|
|
27
|
+
` + source.slice(closingIdx));
|
|
28
|
+
} else
|
|
29
|
+
Logger.warn(
|
|
30
|
+
`r.mountService block not found in ${routerPath}, skipping auto-register.`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
await Bun.write(routerPath, source);
|
|
34
|
+
}, handler = async (args) => {
|
|
35
|
+
const [name, module = "app"] = args;
|
|
36
|
+
if (!name || !module) {
|
|
37
|
+
Logger.error("Usage: gen:service <name> <module: 'app'>");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const nameCapitalized = capitalize(name), moduleSegment = basename(module), moduleCapitalized = capitalize(moduleSegment), cwd = process.cwd(), serviceDir = join(cwd, "src", "modules", module, "services"), filePath = join(serviceDir, `${nameCapitalized}Service.ts`);
|
|
41
|
+
await Bun.$`mkdir -p ${serviceDir}`.quiet(), await Bun.write(filePath, standaloneServiceTemplate(name) + `
|
|
42
|
+
`), Logger.info(`created ${relative(cwd, filePath)}`);
|
|
43
|
+
const routerPath = join(
|
|
44
|
+
cwd,
|
|
45
|
+
"src",
|
|
46
|
+
"modules",
|
|
47
|
+
module,
|
|
48
|
+
`${moduleCapitalized}Router.ts`
|
|
49
|
+
);
|
|
50
|
+
await patchRouter(routerPath, name), Logger.info(`updated ${relative(cwd, routerPath)}`), Logger.info(`Service "${nameCapitalized}Service" generated successfully.`);
|
|
51
|
+
};
|
|
52
|
+
registerCommand({
|
|
53
|
+
name: "gen:service",
|
|
54
|
+
description: "Generate a new Service and register it in the module Router",
|
|
55
|
+
usage: "gen:service <name> <module: 'app'>",
|
|
56
|
+
aliases: ["gen:se"],
|
|
57
|
+
handler
|
|
58
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type CommandHandler = (args: string[], flags: Record<string, string | boolean>) => Promise<void> | void;
|
|
2
|
+
export declare class Command {
|
|
3
|
+
private _name;
|
|
4
|
+
private _handler;
|
|
5
|
+
private _description;
|
|
6
|
+
private _usage;
|
|
7
|
+
private _aliases;
|
|
8
|
+
constructor(name: string, handler: CommandHandler);
|
|
9
|
+
description(description: string): this;
|
|
10
|
+
usage(usage: string): this;
|
|
11
|
+
aliases(aliases: string[]): this;
|
|
12
|
+
getName(): string;
|
|
13
|
+
getHandler(): CommandHandler;
|
|
14
|
+
getDescription(): string;
|
|
15
|
+
getUsage(): string;
|
|
16
|
+
getAliases(): string[];
|
|
17
|
+
}
|
|
18
|
+
export declare const registerCommand: (cmd: Command | {
|
|
19
|
+
name: string;
|
|
20
|
+
handler: CommandHandler;
|
|
21
|
+
description?: string;
|
|
22
|
+
usage?: string;
|
|
23
|
+
aliases?: string[];
|
|
24
|
+
}) => void;
|
|
25
|
+
export declare const getCommand: (name: string) => Command | undefined;
|
|
26
|
+
export declare const getAllCommands: () => Command[];
|