create-nexwire 4.1.2 → 4.2.1

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.
Files changed (54) hide show
  1. package/express/gitignore-stub +31 -24
  2. package/express/package.json +2 -2
  3. package/express/src/database/migrations/sqlite/meta/0000_snapshot.json +411 -411
  4. package/express/src/database/migrations/sqlite/meta/_journal.json +12 -12
  5. package/express/src/framework/http/router.ts +16 -2
  6. package/express/src/framework/maker-cli/db/index.mjs +1 -1
  7. package/express/src/framework/maker-cli/deploy/core.mjs +0 -1
  8. package/express/src/framework/maker-cli/index.mjs +13 -3
  9. package/express/src/framework/maker-cli/module/core.mjs +121 -43
  10. package/express/src/framework/maker-cli/runtime/core.mjs +26 -7
  11. package/express/src/framework/maker-cli/runtime/index.mjs +120 -104
  12. package/express/src/framework/maker-cli/stubs/controller/openapi.ts.stub +6 -6
  13. package/express/src/framework/maker-cli/stubs/controller/plain.ts.stub +6 -6
  14. package/express/src/framework/maker-cli/stubs/helper/name.ts.stub +1 -1
  15. package/express/src/framework/maker-cli/stubs/seeder/name.ts.stub +17 -19
  16. package/express/src/framework/maker-cli/stubs/seeder/standalone.ts.stub +22 -0
  17. package/express/src/framework/maker-cli/stubs/service/name.plain.ts.stub +2 -2
  18. package/express/src/framework/maker-cli/stubs/service/name.ts.stub +1 -1
  19. package/express/src/framework/maker-cli/utils/help.mjs +374 -50
  20. package/express/src/framework/maker-cli/utils/naming.mjs +83 -20
  21. package/express/src/framework/maker-cli/utils/project-commands.mjs +140 -0
  22. package/express/src/framework/queue/queue.ts +402 -342
  23. package/express/src/modules/auth/database/seeders/role.ts +18 -18
  24. package/express/src/modules/auth/database/seeders/user.ts +35 -35
  25. package/express/vitest.config.ts +38 -23
  26. package/hono/gitignore-stub +31 -24
  27. package/hono/package.json +2 -2
  28. package/hono/src/database/migrations/sqlite/meta/0000_snapshot.json +411 -411
  29. package/hono/src/database/migrations/sqlite/meta/_journal.json +12 -12
  30. package/hono/src/framework/database/paginate.ts +253 -253
  31. package/hono/src/framework/http/router.ts +35 -14
  32. package/hono/src/framework/maker-cli/db/index.mjs +1 -1
  33. package/hono/src/framework/maker-cli/deploy/core.mjs +0 -1
  34. package/hono/src/framework/maker-cli/index.mjs +13 -3
  35. package/hono/src/framework/maker-cli/module/core.mjs +116 -38
  36. package/hono/src/framework/maker-cli/runtime/core.mjs +24 -6
  37. package/hono/src/framework/maker-cli/runtime/index.mjs +120 -104
  38. package/hono/src/framework/maker-cli/stubs/controller/openapi.ts.stub +6 -6
  39. package/hono/src/framework/maker-cli/stubs/controller/plain.ts.stub +6 -6
  40. package/hono/src/framework/maker-cli/stubs/helper/name.ts.stub +1 -1
  41. package/hono/src/framework/maker-cli/stubs/seeder/name.ts.stub +17 -19
  42. package/hono/src/framework/maker-cli/stubs/seeder/standalone.ts.stub +22 -0
  43. package/hono/src/framework/maker-cli/stubs/service/name.plain.ts.stub +2 -2
  44. package/hono/src/framework/maker-cli/stubs/service/name.ts.stub +1 -1
  45. package/hono/src/framework/maker-cli/utils/help.mjs +374 -50
  46. package/hono/src/framework/maker-cli/utils/naming.mjs +83 -20
  47. package/hono/src/framework/maker-cli/utils/project-commands.mjs +140 -0
  48. package/hono/src/framework/queue/queue.ts +402 -342
  49. package/hono/src/modules/auth/database/seeders/role.ts +18 -18
  50. package/hono/src/modules/auth/database/seeders/user.ts +35 -35
  51. package/hono/vitest.config.ts +38 -23
  52. package/package.json +1 -1
  53. package/express/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +0 -73
  54. package/hono/src/framework/maker-cli/stubs/controller/openapi.with-model.ts.stub +0 -69
@@ -1,104 +1,120 @@
1
- import { clearViteCache, runRuntime, runTest, runTestCoverage, runTestUI, runTestWatch, runUi, runVite } from "./core.mjs";
2
-
3
- /** Register runtime commands (dev, serve, queue, schedule, UI tools) on the CLI program. */
4
- export function registerRuntimeCommands(program, rawArgs) {
5
- program
6
- .command("dev")
7
- .description("Start API + Vue 3 UI plus optional workers/tools")
8
- .option("--view <tools>", "Comma-separated UI tools to launch (redis,maildev,studio)")
9
- .option("--viewer <tools>", "Alias for --view (npm expands --view to --viewer)")
10
- .option("--with <tools>", "Alias for --view")
11
- .option("--with-redis-view", "Launch Redis Commander")
12
- .option("--with-maildev", "Launch MailDev")
13
- .option("--with-db-studio", "Launch Drizzle Studio")
14
- .allowUnknownOption(true)
15
- .action(async () => runRuntime("dev", rawArgs));
16
- program
17
- .command("serve")
18
- .description("Start HTTP server (dist first if built, else src)")
19
- .option("--prod", "Run production build")
20
- .option("--runtime <name>", "Runtime: node or bun", "node")
21
- .option("--watch", "Watch for file changes (src mode)")
22
- .option("--src", "Force source mode even if dist exists")
23
- .allowUnknownOption(true)
24
- .action(async () => runRuntime("serve", rawArgs));
25
- program
26
- .command("queue:work")
27
- .description("Start queue worker (dist first if built, else src)")
28
- .option("--queue <name>", "Queue name", "default")
29
- .option("--prod", "Run production build")
30
- .option("--runtime <name>", "Runtime: node or bun", "node")
31
- .option("--src", "Force source mode even if dist exists")
32
- .allowUnknownOption(true)
33
- .action(async () => runRuntime("queue:work", rawArgs));
34
- program
35
- .command("queue:clear")
36
- .description("Clear all queue keys")
37
- .allowUnknownOption(true)
38
- .action(async () => runRuntime("queue:clear", rawArgs));
39
- program
40
- .command("schedule:work")
41
- .description("Start scheduler worker (dist first if built, else src)")
42
- .option("--prod", "Run production build")
43
- .option("--runtime <name>", "Runtime: node or bun", "node")
44
- .option("--src", "Force source mode even if dist exists")
45
- .allowUnknownOption(true)
46
- .action(async () => runRuntime("schedule:work", rawArgs));
47
- program
48
- .command("maildev:view")
49
- .description("Start MailDev SMTP and web UI")
50
- .allowUnknownOption(true)
51
- .action(async () => runUi("maildev:view"));
52
- program
53
- .command("redis:view")
54
- .description("Start Redis Commander UI")
55
- .allowUnknownOption(true)
56
- .action(async () => runUi("redis:view"));
57
- program
58
- .command("ui:dev")
59
- .description("Start Vue 3 UI from src/resources")
60
- .allowUnknownOption(true)
61
- .action(async () => runVite("src/resources/vite.config.ts"));
62
- program
63
- .command("admin:dev")
64
- .description("Start admin UI dev server")
65
- .allowUnknownOption(true)
66
- .action(async () => runVite("src/resources/vite.config.ts"));
67
- program
68
- .command("vite:cache:clear")
69
- .description("Clear Vite cache folders (cross-platform)")
70
- .allowUnknownOption(true)
71
- .action(async () => clearViteCache());
72
- program
73
- .command("test")
74
- .description("Run Vitest backend tests")
75
- .allowUnknownOption(true)
76
- .action(async () => {
77
- const args = process.argv.slice(3);
78
- await runTest(args);
79
- });
80
- program
81
- .command("test:watch")
82
- .description("Run Vitest backend tests in watch mode")
83
- .allowUnknownOption(true)
84
- .action(async () => {
85
- const args = process.argv.slice(3);
86
- await runTestWatch(args);
87
- });
88
- program
89
- .command("test:coverage")
90
- .description("Run Vitest backend tests with code coverage")
91
- .allowUnknownOption(true)
92
- .action(async () => {
93
- const args = process.argv.slice(3);
94
- await runTestCoverage(args);
95
- });
96
- program
97
- .command("test:ui")
98
- .description("Run Vitest backend tests in UI mode")
99
- .allowUnknownOption(true)
100
- .action(async () => {
101
- const args = process.argv.slice(3);
102
- await runTestUI(args);
103
- });
104
- }
1
+ import { clearViteCache, runRuntime, runTest, runTestCoverage, runTestUI, runTestWatch, runUi, runVite } from "./core.mjs";
2
+ import { initProjectCommands, PROJECT_COMMANDS_PATH } from "../utils/project-commands.mjs";
3
+
4
+ /** Register runtime commands (dev, serve, queue, schedule, UI tools) on the CLI program. */
5
+ export function registerRuntimeCommands(program, rawArgs) {
6
+ program
7
+ .command("dev")
8
+ .description("Start API + Vue 3 UI plus optional workers/tools")
9
+ .option("--view <tools>", "Comma-separated UI tools to launch (redis,maildev,studio)")
10
+ .option("--viewer <tools>", "Alias for --view (npm expands --view to --viewer)")
11
+ .option("--with <tools>", "Alias for --view")
12
+ .option("--with-redis-view", "Launch Redis Commander")
13
+ .option("--with-maildev", "Launch MailDev")
14
+ .option("--with-db-studio", "Launch Drizzle Studio")
15
+ .allowUnknownOption(true)
16
+ .action(async () => runRuntime("dev", rawArgs));
17
+ program
18
+ .command("serve")
19
+ .description("Start HTTP server (dist first if built, else src)")
20
+ .option("--prod", "Run production build")
21
+ .option("--runtime <name>", "Runtime: node or bun", "node")
22
+ .option("--watch", "Watch for file changes (src mode)")
23
+ .option("--src", "Force source mode even if dist exists")
24
+ .allowUnknownOption(true)
25
+ .action(async () => runRuntime("serve", rawArgs));
26
+ program
27
+ .command("queue:work")
28
+ .description("Start queue worker (dist first if built, else src)")
29
+ .option("--queue <name>", "Queue name", "default")
30
+ .option("--prod", "Run production build")
31
+ .option("--runtime <name>", "Runtime: node or bun", "node")
32
+ .option("--src", "Force source mode even if dist exists")
33
+ .allowUnknownOption(true)
34
+ .action(async () => runRuntime("queue:work", rawArgs));
35
+ program
36
+ .command("queue:clear")
37
+ .description("Clear all queue keys")
38
+ .allowUnknownOption(true)
39
+ .action(async () => runRuntime("queue:clear", rawArgs));
40
+ program
41
+ .command("schedule:work")
42
+ .description("Start scheduler worker (dist first if built, else src)")
43
+ .option("--prod", "Run production build")
44
+ .option("--runtime <name>", "Runtime: node or bun", "node")
45
+ .option("--src", "Force source mode even if dist exists")
46
+ .allowUnknownOption(true)
47
+ .action(async () => runRuntime("schedule:work", rawArgs));
48
+ program
49
+ .command("maildev:view")
50
+ .description("Start MailDev SMTP and web UI")
51
+ .allowUnknownOption(true)
52
+ .action(async () => runUi("maildev:view"));
53
+ program
54
+ .command("redis:view")
55
+ .description("Start Redis Commander UI")
56
+ .allowUnknownOption(true)
57
+ .action(async () => runUi("redis:view"));
58
+ program
59
+ .command("ui:dev")
60
+ .description("Start Vue 3 UI from src/resources")
61
+ .allowUnknownOption(true)
62
+ .action(async () => runVite("src/resources/vite.config.ts"));
63
+ program
64
+ .command("admin:dev")
65
+ .description("Start admin UI dev server")
66
+ .allowUnknownOption(true)
67
+ .action(async () => runVite("src/resources/vite.config.ts"));
68
+ program
69
+ .command("vite:cache:clear")
70
+ .description("Clear Vite cache folders (cross-platform)")
71
+ .allowUnknownOption(true)
72
+ .action(async () => clearViteCache());
73
+ program
74
+ .command("maker:init")
75
+ .description(`Create ${PROJECT_COMMANDS_PATH} for your own commands`)
76
+ .option("--force", "Overwrite an existing file")
77
+ .allowUnknownOption(true)
78
+ .action(async (options) => {
79
+ const { created, overwritten } = await initProjectCommands(process.cwd(), { force: Boolean(options?.force) });
80
+ // created = written into a new file; overwritten = replaced under --force.
81
+ // Neither means the file was already there and was left alone.
82
+ console.log(
83
+ created || overwritten
84
+ ? `Add your commands to ${PROJECT_COMMANDS_PATH}, then run: maker --help`
85
+ : `${PROJECT_COMMANDS_PATH} already exists and was left alone. Edit it to add commands, or re-run with --force to replace it.`
86
+ );
87
+ });
88
+ program
89
+ .command("test")
90
+ .description("Run Vitest backend tests")
91
+ .allowUnknownOption(true)
92
+ .action(async () => {
93
+ const args = process.argv.slice(3);
94
+ await runTest(args);
95
+ });
96
+ program
97
+ .command("test:watch")
98
+ .description("Run Vitest backend tests in watch mode")
99
+ .allowUnknownOption(true)
100
+ .action(async () => {
101
+ const args = process.argv.slice(3);
102
+ await runTestWatch(args);
103
+ });
104
+ program
105
+ .command("test:coverage")
106
+ .description("Run Vitest backend tests with code coverage")
107
+ .allowUnknownOption(true)
108
+ .action(async () => {
109
+ const args = process.argv.slice(3);
110
+ await runTestCoverage(args);
111
+ });
112
+ program
113
+ .command("test:ui")
114
+ .description("Run Vitest backend tests in UI mode")
115
+ .allowUnknownOption(true)
116
+ .action(async () => {
117
+ const args = process.argv.slice(3);
118
+ await runTestUI(args);
119
+ });
120
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Request, Response } from "express";
2
2
  import { HttpStatusCodes } from "@/framework/facade.js";
3
- import { {{controller}}Service } from "@/modules/{{module}}/services/{{controller}}.js";
3
+ import { {{ServiceName}} } from "@/modules/{{module}}/services/{{controller}}.js";
4
4
 
5
5
  /**
6
6
  * Why: Returns every {{controller}} row for list screens.
@@ -8,7 +8,7 @@ import { {{controller}}Service } from "@/modules/{{module}}/services/{{controlle
8
8
  * Where: GET /{{controller}} route.
9
9
  */
10
10
  export const index = async (_req: Request, res: Response) => {
11
- const data = await {{controller}}Service.list();
11
+ const data = await {{ServiceName}}.list();
12
12
 
13
13
  res.json({ message: "{{controller}} list fetched successfully", data });
14
14
  };
@@ -19,7 +19,7 @@ export const index = async (_req: Request, res: Response) => {
19
19
  * Where: GET /{{controller}}/{id} route.
20
20
  */
21
21
  export const show = async (req: Request, res: Response) => {
22
- const data = await {{controller}}Service.findOne(Number(req.params.id));
22
+ const data = await {{ServiceName}}.findOne(Number(req.params.id));
23
23
 
24
24
  if (!data) {
25
25
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -35,7 +35,7 @@ export const show = async (req: Request, res: Response) => {
35
35
  * Where: POST /{{controller}} route.
36
36
  */
37
37
  export const store = async (req: Request, res: Response) => {
38
- const data = await {{controller}}Service.create(req.body);
38
+ const data = await {{ServiceName}}.create(req.body);
39
39
 
40
40
  res.status(HttpStatusCodes.CREATED).json({ message: "{{controller}} created successfully", data });
41
41
  };
@@ -46,7 +46,7 @@ export const store = async (req: Request, res: Response) => {
46
46
  * Where: PUT/PATCH /{{controller}}/{id} route.
47
47
  */
48
48
  export const update = async (req: Request, res: Response) => {
49
- const data = await {{controller}}Service.update(Number(req.params.id), req.body);
49
+ const data = await {{ServiceName}}.update(Number(req.params.id), req.body);
50
50
 
51
51
  if (!data) {
52
52
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -62,7 +62,7 @@ export const update = async (req: Request, res: Response) => {
62
62
  * Where: DELETE /{{controller}}/{id} route.
63
63
  */
64
64
  export const destroy = async (req: Request, res: Response) => {
65
- const data = await {{controller}}Service.remove(Number(req.params.id));
65
+ const data = await {{ServiceName}}.remove(Number(req.params.id));
66
66
 
67
67
  if (!data) {
68
68
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -2,7 +2,7 @@ import type { Request, Response } from "express";
2
2
  import { HttpStatusCodes } from "@/framework/facade.js";
3
3
  import { validate } from "@/framework/facade.js";
4
4
  import { Create{{ClassName}}Schema, Update{{ClassName}}Schema, {{ClassName}}IdParamsSchema } from "@/modules/{{module}}/schemas/{{controller}}.js";
5
- import { {{controller}}Service } from "@/modules/{{module}}/services/{{controller}}.js";
5
+ import { {{ServiceName}} } from "@/modules/{{module}}/services/{{controller}}.js";
6
6
 
7
7
  /**
8
8
  * Why: Returns every {{controller}} row for list screens.
@@ -10,7 +10,7 @@ import { {{controller}}Service } from "@/modules/{{module}}/services/{{controlle
10
10
  * Where: GET /{{controller}} route.
11
11
  */
12
12
  export const index = async (_req: Request, res: Response) => {
13
- const data = await {{controller}}Service.list();
13
+ const data = await {{ServiceName}}.list();
14
14
 
15
15
  res.json({ message: "{{controller}} list fetched successfully", data });
16
16
  };
@@ -22,7 +22,7 @@ export const index = async (_req: Request, res: Response) => {
22
22
  */
23
23
  export const show = async (req: Request, res: Response) => {
24
24
  const params = await validate({{ClassName}}IdParamsSchema, req.params);
25
- const data = await {{controller}}Service.findOne(params.id);
25
+ const data = await {{ServiceName}}.findOne(params.id);
26
26
 
27
27
  if (!data) {
28
28
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -39,7 +39,7 @@ export const show = async (req: Request, res: Response) => {
39
39
  */
40
40
  export const store = async (req: Request, res: Response) => {
41
41
  const body = await validate(Create{{ClassName}}Schema, req.body);
42
- const data = await {{controller}}Service.create(body);
42
+ const data = await {{ServiceName}}.create(body);
43
43
 
44
44
  res.status(HttpStatusCodes.CREATED).json({ message: "{{controller}} created successfully", data });
45
45
  };
@@ -52,7 +52,7 @@ export const store = async (req: Request, res: Response) => {
52
52
  export const update = async (req: Request, res: Response) => {
53
53
  const params = await validate({{ClassName}}IdParamsSchema, req.params);
54
54
  const body = await validate(Update{{ClassName}}Schema, req.body);
55
- const data = await {{controller}}Service.update(params.id, body);
55
+ const data = await {{ServiceName}}.update(params.id, body);
56
56
 
57
57
  if (!data) {
58
58
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -69,7 +69,7 @@ export const update = async (req: Request, res: Response) => {
69
69
  */
70
70
  export const destroy = async (req: Request, res: Response) => {
71
71
  const params = await validate({{ClassName}}IdParamsSchema, req.params);
72
- const data = await {{controller}}Service.remove(params.id);
72
+ const data = await {{ServiceName}}.remove(params.id);
73
73
 
74
74
  if (!data) {
75
75
  res.status(HttpStatusCodes.NOT_FOUND).json({ message: "{{controller}} not found" });
@@ -9,6 +9,6 @@
9
9
  * When: Replace this with real logic and rename it.
10
10
  * Where: Anywhere inside the {{module}} module.
11
11
  */
12
- export function {{name}}Helper<T>(value: T): T {
12
+ export function {{Name}}Helper<T>(value: T): T {
13
13
  return value;
14
14
  }
@@ -1,20 +1,18 @@
1
- import { db } from "@/framework/facade.js";
2
- import { {{tableVariable}} } from "@/modules/{{module}}/database/models/{{name}}.js";
3
-
4
- export const table = {{tableVariable}};
5
-
6
- export default async function {{ClassName}}Seeder() {
7
- const rows = [
8
- // Add your seed data here
9
- // Example:
10
- // { name: "{{ClassName}} 1", description: "This is the first {{name}}" },
11
- // { name: "{{ClassName}} 2", description: "This is the second {{name}}" }
12
- ];
13
-
14
- for (const row of rows) {
15
- await db.insert({{tableVariable}}).values(row);
16
- }
17
-
18
- console.log("{{ClassName}} seeder completed");
19
- }
1
+ import { db } from "@/framework/facade.js";
2
+ import { {{tableVariable}} } from "@/modules/{{module}}/database/models/{{name}}.js";
3
+
4
+ export const table = {{tableVariable}};
5
+
6
+ export default async function {{ClassName}}Seeder() {
7
+ const rows = [
8
+ // Add your seed data here
9
+ // Example:
10
+ // { name: "{{ClassName}} 1", description: "This is the first {{name}}" },
11
+ // { name: "{{ClassName}} 2", description: "This is the second {{name}}" }
12
+ ];
13
+
14
+ for (const row of rows) await db.insert({{tableVariable}}).values(row);
15
+
16
+ console.log(`{{ClassName}}: ${rows.length} row(s) prepared`);
17
+ }
20
18
 
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Standalone seeder for "{{name}}" — no model of that name exists in module
3
+ * "{{module}}", so nothing was imported for you. Uncomment the two lines below,
4
+ * point them at the table you want, then add your rows.
5
+ *
6
+ * Run with: bun maker module:seed {{module}}
7
+ */
8
+
9
+ import { db } from "@/framework/facade.js";
10
+ // import { {{tableVariable}} } from "@/modules/{{module}}/database/models/{{name}}.js";
11
+ // export const table = {{tableVariable}};
12
+
13
+ export default async function {{ClassName}}Seeder() {
14
+ const rows: Record<string, unknown>[] = [
15
+ // { name: "{{ClassName}} 1" },
16
+ // { name: "{{ClassName}} 2" }
17
+ ];
18
+
19
+ // for (const row of rows) await db.insert({{tableVariable}}).values(row);
20
+
21
+ console.log(`{{ClassName}}: ${rows.length} row(s) ready`);
22
+ }
@@ -10,10 +10,10 @@ import { db } from "@/framework/facade.js";
10
10
  * import { {{tableVariable}} } from "@/modules/{{module}}/database/models/{{controller}}.js";
11
11
  * return db.select().from({{tableVariable}});
12
12
  */
13
- export const {{controller}}Service = {
13
+ export const {{ServiceName}} = {
14
14
  /**
15
15
  * Why: CRUD service for {{controller}}.
16
- * When: Consumed directly by the controller as `{{controller}}Service.list()`, etc.
16
+ * When: Consumed directly by the controller as `{{ServiceName}}.list()`, etc.
17
17
  * Where: Wired into the module's controller handlers.
18
18
  */
19
19
  list: async () => {
@@ -2,7 +2,7 @@ import { eq } from "drizzle-orm";
2
2
  import { db } from "@/framework/facade.js";
3
3
  import { {{tableVariable}} } from "@/modules/{{module}}/database/models/{{controller}}.js";
4
4
 
5
- export const {{controller}}Service = {
5
+ export const {{ServiceName}} = {
6
6
  /**
7
7
  * Why: Returns every {{controller}} row for list screens.
8
8
  * When: Called by the controller's index() handler.