create-craftjs 1.0.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 +137 -0
- package/bin/index.js +158 -0
- package/package.json +24 -0
- package/template/.dockerignore +4 -0
- package/template/Dockerfile +12 -0
- package/template/babel.config.json +3 -0
- package/template/craft/commands/build.js +15 -0
- package/template/craft/commands/db-fresh.js +22 -0
- package/template/craft/commands/db-generate.js +23 -0
- package/template/craft/commands/db-migrate.js +22 -0
- package/template/craft/commands/dev.js +16 -0
- package/template/craft/commands/key-generate.js +41 -0
- package/template/craft/commands/make-apidocs.js +121 -0
- package/template/craft/commands/make-command.js +38 -0
- package/template/craft/commands/make-dto.js +39 -0
- package/template/craft/commands/make-middleware.js +46 -0
- package/template/craft/commands/make-repository.js +36 -0
- package/template/craft/commands/make-route.js +88 -0
- package/template/craft/commands/make-service.js +39 -0
- package/template/craft/commands/make-test.js +48 -0
- package/template/craft/commands/make-utils.js +30 -0
- package/template/craft/commands/make-validation.js +42 -0
- package/template/craft/commands/make-view.js +42 -0
- package/template/craft/commands/start.js +29 -0
- package/template/craft/commands/test.js +20 -0
- package/template/craft.js +256 -0
- package/template/nodemon.json +6 -0
- package/template/package-lock.json +8777 -0
- package/template/package.json +79 -0
- package/template/prisma/migrations/20250518142257_create_table_users/migration.sql +13 -0
- package/template/prisma/migrations/migration_lock.toml +3 -0
- package/template/prisma/schema.prisma +22 -0
- package/template/prisma/seed.ts +29 -0
- package/template/public/assets/images/default-user.png +0 -0
- package/template/src/apidocs/auth-docs.ts +314 -0
- package/template/src/apidocs/users-docs.ts +240 -0
- package/template/src/config/database.ts +90 -0
- package/template/src/config/env.ts +29 -0
- package/template/src/config/logger.ts +116 -0
- package/template/src/config/web.ts +40 -0
- package/template/src/controllers/auth-controller.ts +88 -0
- package/template/src/controllers/user-controller.ts +79 -0
- package/template/src/dtos/list-dto.ts +12 -0
- package/template/src/dtos/user-dto.ts +57 -0
- package/template/src/main.ts +28 -0
- package/template/src/middleware/auth-middleware.ts +44 -0
- package/template/src/middleware/error-middleware.ts +27 -0
- package/template/src/middleware/http-logger-middleware.ts +31 -0
- package/template/src/repositories/user-repository.ts +75 -0
- package/template/src/routes/auth-route.ts +20 -0
- package/template/src/routes/main-route.ts +25 -0
- package/template/src/routes/user-route.ts +35 -0
- package/template/src/services/auth-service.ts +162 -0
- package/template/src/services/user-service.ts +102 -0
- package/template/src/types/type-request.ts +6 -0
- package/template/src/utils/async-handler.ts +9 -0
- package/template/src/utils/response-error.ts +10 -0
- package/template/src/utils/response.ts +60 -0
- package/template/src/utils/swagger.ts +135 -0
- package/template/src/utils/validation.ts +7 -0
- package/template/src/validations/user-validation.ts +127 -0
- package/template/src/views/index.ejs +6 -0
- package/template/src/views/layouts/main.ejs +14 -0
- package/template/src/views/partials/header.ejs +3 -0
- package/template/test/user.test.ts +16 -0
- package/template/tsconfig.json +13 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
const toCamelCase = (str) =>
|
|
6
|
+
str
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.split("-")
|
|
9
|
+
.map((word, i) => (i === 0 ? word : word[0].toUpperCase() + word.slice(1)))
|
|
10
|
+
.join("");
|
|
11
|
+
|
|
12
|
+
function makeMiddleware(name) {
|
|
13
|
+
if (!name) {
|
|
14
|
+
console.log(chalk.red("❌ Please provide a middleware name."));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const className = `${toCamelCase(name)}Middleware`;
|
|
19
|
+
const fileName = `${name.toLowerCase()}-middleware.ts`;
|
|
20
|
+
const targetDir = path.resolve("src", "middleware");
|
|
21
|
+
|
|
22
|
+
if (!fs.existsSync(targetDir)) {
|
|
23
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const filePath = path.join(targetDir, fileName);
|
|
27
|
+
if (fs.existsSync(filePath)) {
|
|
28
|
+
console.log(chalk.yellow("⚠️ Middleware already exists."));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const content = `import { NextFunction, Request, Response } from "express";
|
|
33
|
+
|
|
34
|
+
export const ${className} = async (
|
|
35
|
+
req: Request,
|
|
36
|
+
res: Response,
|
|
37
|
+
next: NextFunction
|
|
38
|
+
) => {
|
|
39
|
+
next();
|
|
40
|
+
};
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
fs.writeFileSync(filePath, content);
|
|
44
|
+
console.log(chalk.green(`✅ Middleware created at ${filePath}`));
|
|
45
|
+
}
|
|
46
|
+
module.exports = makeMiddleware;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const toPascalCase = (str) =>
|
|
5
|
+
str.replace(/(^\w|-\w)/g, (m) => m.replace("-", "").toUpperCase());
|
|
6
|
+
|
|
7
|
+
function makeRepository(name) {
|
|
8
|
+
if (!name) {
|
|
9
|
+
console.log(chalk.red("❌ Please provide a repository name."));
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const className = `${toPascalCase(name)}Repository`;
|
|
14
|
+
const fileName = `${name.toLowerCase()}-repository.ts`;
|
|
15
|
+
const targetDir = path.resolve("src", "repositories");
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(targetDir)) {
|
|
18
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const filePath = path.join(targetDir, fileName);
|
|
22
|
+
if (fs.existsSync(filePath)) {
|
|
23
|
+
console.log(chalk.yellow("⚠️ Repository already exists."));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const content = `import { prismaClient } from "../config/database";
|
|
28
|
+
|
|
29
|
+
export class ${className} {
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
fs.writeFileSync(filePath, content);
|
|
34
|
+
console.log(chalk.green(`✅ Repository created at ${filePath}`));
|
|
35
|
+
}
|
|
36
|
+
module.exports = makeRepository;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
const toPascalCase = (str) =>
|
|
6
|
+
str.replace(/(^\w|-\w)/g, (m) => m.replace("-", "").toUpperCase());
|
|
7
|
+
|
|
8
|
+
function makeRoute(name) {
|
|
9
|
+
if (!name) {
|
|
10
|
+
console.log(chalk.red("❌ Please provide a route name."));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const routeName = name.toLowerCase();
|
|
15
|
+
const className = `${toPascalCase(name)}Controller`;
|
|
16
|
+
const routeConst = `${routeName}Router`;
|
|
17
|
+
const fileName = `${routeName}-route.ts`;
|
|
18
|
+
const targetDir = path.resolve("src", "routes");
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(targetDir)) {
|
|
21
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const filePath = path.join(targetDir, fileName);
|
|
25
|
+
if (fs.existsSync(filePath)) {
|
|
26
|
+
console.log(chalk.yellow("⚠️ Route already exists."));
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const content = `import express from "express";
|
|
31
|
+
import { asyncHandler } from "../utils/async-handler";
|
|
32
|
+
import { authMiddleware } from "../middleware/auth-middleware";
|
|
33
|
+
|
|
34
|
+
import { ${className} } from "../controllers/${routeName}-controller";
|
|
35
|
+
|
|
36
|
+
export const ${routeConst} = express.Router();
|
|
37
|
+
|
|
38
|
+
// Example routes:
|
|
39
|
+
${routeConst}.get("/api/${routeName}s", asyncHandler(authMiddleware), ${className}.index);
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
fs.writeFileSync(filePath, content);
|
|
43
|
+
console.log(chalk.green(`✅ Route created at ${filePath}`));
|
|
44
|
+
|
|
45
|
+
const mainRouterPath = path.resolve("src", "routes", "main-route.ts");
|
|
46
|
+
|
|
47
|
+
if (fs.existsSync(mainRouterPath)) {
|
|
48
|
+
let mainRouterContent = fs.readFileSync(mainRouterPath, "utf-8");
|
|
49
|
+
|
|
50
|
+
const importStatement = `import { ${routeConst} } from "./${routeName}-route";`;
|
|
51
|
+
const useStatement = `mainRouter.use(${routeConst});`;
|
|
52
|
+
|
|
53
|
+
if (!mainRouterContent.includes(importStatement)) {
|
|
54
|
+
const lines = mainRouterContent.split("\n");
|
|
55
|
+
const importIndex = lines.findIndex((line) => line.startsWith("import"));
|
|
56
|
+
const lastImportIndex = [...lines]
|
|
57
|
+
.reverse()
|
|
58
|
+
.findIndex((line) => line.startsWith("import"));
|
|
59
|
+
const insertIndex =
|
|
60
|
+
lastImportIndex >= 0 ? lines.length - lastImportIndex : 0;
|
|
61
|
+
lines.splice(insertIndex, 0, importStatement);
|
|
62
|
+
mainRouterContent = lines.join("\n");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!mainRouterContent.includes(useStatement)) {
|
|
66
|
+
const routerEndIndex = mainRouterContent.lastIndexOf("mainRouter.use(");
|
|
67
|
+
const insertIndex =
|
|
68
|
+
routerEndIndex >= 0
|
|
69
|
+
? mainRouterContent.indexOf("\n", routerEndIndex) + 1
|
|
70
|
+
: mainRouterContent.length;
|
|
71
|
+
|
|
72
|
+
mainRouterContent =
|
|
73
|
+
mainRouterContent.slice(0, insertIndex) +
|
|
74
|
+
useStatement +
|
|
75
|
+
"\n" +
|
|
76
|
+
mainRouterContent.slice(insertIndex);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fs.writeFileSync(mainRouterPath, mainRouterContent);
|
|
80
|
+
console.log(chalk.green("✅ Route registered in main-router."));
|
|
81
|
+
} else {
|
|
82
|
+
console.log(
|
|
83
|
+
chalk.yellow("⚠️ main-route.ts not found. Please register manually.")
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = makeRoute;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
const toPascalCase = (str) =>
|
|
6
|
+
str.replace(/(^\w|-\w)/g, (m) => m.replace("-", "").toUpperCase());
|
|
7
|
+
|
|
8
|
+
function makeService(name) {
|
|
9
|
+
if (!name) {
|
|
10
|
+
console.log(chalk.red("❌ Please provide a service name."));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const className = `${toPascalCase(name)}Service`;
|
|
15
|
+
const fileName = `${name.toLowerCase()}-service.ts`;
|
|
16
|
+
const targetDir = path.resolve("src", "services");
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(targetDir)) {
|
|
19
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const filePath = path.join(targetDir, fileName);
|
|
23
|
+
if (fs.existsSync(filePath)) {
|
|
24
|
+
console.log(chalk.yellow("⚠️ Service already exists."));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const content = `export class ${className} {
|
|
29
|
+
async doSomething() {
|
|
30
|
+
return "Service ${className} is working";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
fs.writeFileSync(filePath, content);
|
|
36
|
+
console.log(chalk.green(`✅ Service created at ${filePath}`));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = makeService;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
function MakeTest(name) {
|
|
6
|
+
if (!name) {
|
|
7
|
+
console.log(chalk.red("❌ Please provide a test file name."));
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const testDir = path.resolve(process.cwd(), "test");
|
|
12
|
+
if (!fs.existsSync(testDir)) {
|
|
13
|
+
fs.mkdirSync(testDir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const fileName = name.endsWith(".test.ts") ? name : `${name}.test.ts`;
|
|
17
|
+
const filePath = path.join(testDir, fileName);
|
|
18
|
+
|
|
19
|
+
if (fs.existsSync(filePath)) {
|
|
20
|
+
console.log(chalk.red(`❌ Test file already exists: ${fileName}`));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const template = `import supertest from "supertest";
|
|
25
|
+
import { web } from "../src/application/web";
|
|
26
|
+
import { logger } from "../src/application/logging";
|
|
27
|
+
|
|
28
|
+
// example
|
|
29
|
+
describe("POST /api/users", () => {
|
|
30
|
+
it("should register new user", async () => {
|
|
31
|
+
const response = await supertest(web).post("/api/auth/register").send({
|
|
32
|
+
fullName: "test",
|
|
33
|
+
email: "testing@gmail.com",
|
|
34
|
+
password: "12345678",
|
|
35
|
+
});
|
|
36
|
+
logger.debug(response.body);
|
|
37
|
+
expect(response.status).toBe(201);
|
|
38
|
+
expect(response.body.data.fullName).toBe("test");
|
|
39
|
+
expect(response.body.data.email).toBe("testing@gmail.com");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
fs.writeFileSync(filePath, template, "utf-8");
|
|
45
|
+
console.log(chalk.green(`✅ Test file created at: ${filePath}`));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = MakeTest;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
function makeUtils(name) {
|
|
6
|
+
if (!name) {
|
|
7
|
+
console.log(chalk.red("❌ Please provide a utils name."));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const fileName = `${name.toLowerCase()}.ts`;
|
|
12
|
+
const targetDir = path.resolve("src", "utils");
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(targetDir)) {
|
|
15
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const filePath = path.join(targetDir, fileName);
|
|
19
|
+
if (fs.existsSync(filePath)) {
|
|
20
|
+
console.log(chalk.yellow("⚠️ Utils already exists."));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const content = ``;
|
|
25
|
+
|
|
26
|
+
fs.writeFileSync(filePath, content);
|
|
27
|
+
console.log(chalk.green(`✅ Utils created at ${filePath}`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = makeUtils;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
const toPascalCase = (str) =>
|
|
6
|
+
str.replace(/(^\w|-\w)/g, (m) => m.replace("-", "").toUpperCase());
|
|
7
|
+
|
|
8
|
+
function makeValidation(name) {
|
|
9
|
+
if (!name) {
|
|
10
|
+
console.log(chalk.red("❌ Please provide a validation name."));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const className = `${toPascalCase(name)}Validation`;
|
|
15
|
+
const fileName = `${name.toLowerCase()}-validation.ts`;
|
|
16
|
+
const targetDir = path.resolve("src", "validations");
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(targetDir)) {
|
|
19
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const filePath = path.join(targetDir, fileName);
|
|
23
|
+
if (fs.existsSync(filePath)) {
|
|
24
|
+
console.log(chalk.yellow("⚠️ Validation already exists."));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const content = `import { z, ZodType } from "zod";
|
|
29
|
+
|
|
30
|
+
export class ${className} {
|
|
31
|
+
static readonly CREATE: ZodType = z.object({
|
|
32
|
+
field1: z.string().min(1, { message: "Field1 wajib diisi" }),
|
|
33
|
+
field2: z.number().optional(),
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
fs.writeFileSync(filePath, content);
|
|
40
|
+
console.log(chalk.green(`✅ Validation created at ${filePath}`));
|
|
41
|
+
}
|
|
42
|
+
module.exports = makeValidation;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
function makeView(name) {
|
|
6
|
+
if (!name) {
|
|
7
|
+
console.log(chalk.red("❌ Please provide a view name."));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const fileName = `${name.toLowerCase()}.ejs`;
|
|
12
|
+
const targetDir = path.resolve("src", "views");
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(targetDir)) {
|
|
15
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const filePath = path.join(targetDir, fileName);
|
|
19
|
+
if (fs.existsSync(filePath)) {
|
|
20
|
+
console.log(chalk.yellow("⚠️ View already exists."));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const content = `<!DOCTYPE html>
|
|
25
|
+
<html lang="en">
|
|
26
|
+
<head>
|
|
27
|
+
<meta charset="UTF-8" />
|
|
28
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
29
|
+
<title><%= title %></title>
|
|
30
|
+
</head>
|
|
31
|
+
<body
|
|
32
|
+
<p>${name}</p>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
fs.writeFileSync(filePath, content);
|
|
39
|
+
console.log(chalk.green(`✅ View created at ${filePath}`));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = makeView;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
function Start() {
|
|
7
|
+
const entryPoint = path.resolve("dist/main.js");
|
|
8
|
+
|
|
9
|
+
if (!fs.existsSync(entryPoint)) {
|
|
10
|
+
console.error(
|
|
11
|
+
chalk.red(
|
|
12
|
+
`❌ Build file not found: ${entryPoint}\nPlease run 'node craft build' before starting the production server.`
|
|
13
|
+
)
|
|
14
|
+
);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
console.log(chalk.blue("🚀 Starting production server...."));
|
|
19
|
+
const result = spawnSync("node", [entryPoint], {
|
|
20
|
+
stdio: "inherit",
|
|
21
|
+
shell: true,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (result.status !== 0) {
|
|
25
|
+
console.error(chalk.red("❌ Failed to start production server."));
|
|
26
|
+
process.exit(result.status ?? 1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
module.exports = Start;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
|
|
4
|
+
function RunTest() {
|
|
5
|
+
console.log(chalk.blue("🧪 Running tests..."));
|
|
6
|
+
|
|
7
|
+
const result = spawnSync("npx", ["jest", "-i"], {
|
|
8
|
+
stdio: "inherit",
|
|
9
|
+
shell: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (result.status !== 0) {
|
|
13
|
+
console.error(chalk.red("❌ Tests failed."));
|
|
14
|
+
process.exit(result.status ?? 1);
|
|
15
|
+
} else {
|
|
16
|
+
console.log(chalk.green("✅ Tests passed."));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = RunTest;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const yargs = require("yargs");
|
|
4
|
+
const { hideBin } = require("yargs/helpers");
|
|
5
|
+
|
|
6
|
+
yargs(hideBin(process.argv))
|
|
7
|
+
.command(
|
|
8
|
+
"build",
|
|
9
|
+
"Building project to production ",
|
|
10
|
+
() => {},
|
|
11
|
+
() => {
|
|
12
|
+
const build = require("./craft/commands/build.js");
|
|
13
|
+
build();
|
|
14
|
+
}
|
|
15
|
+
)
|
|
16
|
+
.command(
|
|
17
|
+
"db:generate",
|
|
18
|
+
"Running prisma generate",
|
|
19
|
+
() => {},
|
|
20
|
+
() => {
|
|
21
|
+
const dbgenerate = require("./craft/commands/db-generate.js");
|
|
22
|
+
dbgenerate();
|
|
23
|
+
}
|
|
24
|
+
)
|
|
25
|
+
.command(
|
|
26
|
+
"db:migrate",
|
|
27
|
+
"Running prisma migration",
|
|
28
|
+
() => {},
|
|
29
|
+
() => {
|
|
30
|
+
const migrate = require("./craft/commands/db-migrate.js");
|
|
31
|
+
migrate();
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
.command(
|
|
35
|
+
"db:fresh",
|
|
36
|
+
"Running prisma migrate fresh",
|
|
37
|
+
() => {},
|
|
38
|
+
() => {
|
|
39
|
+
const dbfresh = require("./craft/commands/db-fresh.js");
|
|
40
|
+
dbfresh();
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
.command(
|
|
44
|
+
"dev",
|
|
45
|
+
"Starting development server",
|
|
46
|
+
() => {},
|
|
47
|
+
() => {
|
|
48
|
+
const dev = require("./craft/commands/dev.js");
|
|
49
|
+
dev();
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
.command(
|
|
53
|
+
"key:generate",
|
|
54
|
+
"Generate JWT SECRET KEY",
|
|
55
|
+
() => {},
|
|
56
|
+
() => {
|
|
57
|
+
const dev = require("./craft/commands/key-generate.js");
|
|
58
|
+
dev();
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
.command(
|
|
62
|
+
"make:apidocs <name>",
|
|
63
|
+
"Generate a new api documentation",
|
|
64
|
+
(yargs) => {
|
|
65
|
+
yargs.positional("name", {
|
|
66
|
+
describe: "apidocs name",
|
|
67
|
+
type: "string",
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
(argv) => {
|
|
71
|
+
const makeapidocs = require("./craft/commands/make-apidocs.js");
|
|
72
|
+
makeapidocs(argv.name);
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
.command(
|
|
76
|
+
"make:command <name>",
|
|
77
|
+
"Generate a new craft command",
|
|
78
|
+
(yargs) => {
|
|
79
|
+
yargs.positional("name", {
|
|
80
|
+
describe: "Command name",
|
|
81
|
+
type: "string",
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
(argv) => {
|
|
85
|
+
const makecommand = require("./craft/commands/make-command.js");
|
|
86
|
+
makecommand(argv.name);
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
.command(
|
|
90
|
+
"make:controller <name>",
|
|
91
|
+
"Generate a new controller",
|
|
92
|
+
(yargs) => {
|
|
93
|
+
yargs
|
|
94
|
+
.positional("name", {
|
|
95
|
+
describe: "Controller name",
|
|
96
|
+
type: "string",
|
|
97
|
+
})
|
|
98
|
+
.option("resource", {
|
|
99
|
+
describe: "Generate resource style controller methods",
|
|
100
|
+
type: "boolean",
|
|
101
|
+
default: false,
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
(argv) => {
|
|
105
|
+
const makecontroller = require("./craft/commands/make-controller.js");
|
|
106
|
+
makecontroller(argv.name, { resource: argv.resource });
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
.command(
|
|
110
|
+
"make:middleware <name>",
|
|
111
|
+
"Generate a new middleware",
|
|
112
|
+
(yargs) => {
|
|
113
|
+
yargs.positional("name", {
|
|
114
|
+
describe: "Middleware name",
|
|
115
|
+
type: "string",
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
(argv) => {
|
|
119
|
+
const makemiddleware = require("./craft/commands/make-middleware.js");
|
|
120
|
+
makemiddleware(argv.name);
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
.command(
|
|
124
|
+
"make:repository <name>",
|
|
125
|
+
"Generate a new respository",
|
|
126
|
+
(yargs) => {
|
|
127
|
+
yargs.positional("name", {
|
|
128
|
+
describe: "Repository name",
|
|
129
|
+
type: "string",
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
(argv) => {
|
|
133
|
+
const makerepository = require("./craft/commands/make-repository.js");
|
|
134
|
+
makerepository(argv.name);
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
.command(
|
|
138
|
+
"make:dto <name>",
|
|
139
|
+
"Generate a new dto",
|
|
140
|
+
(yargs) => {
|
|
141
|
+
yargs.positional("name", {
|
|
142
|
+
describe: "Dto name",
|
|
143
|
+
type: "string",
|
|
144
|
+
});
|
|
145
|
+
},
|
|
146
|
+
(argv) => {
|
|
147
|
+
const makedto = require("./craft/commands/make-dto.js");
|
|
148
|
+
makedto(argv.name);
|
|
149
|
+
}
|
|
150
|
+
)
|
|
151
|
+
.command(
|
|
152
|
+
"make:route <name>",
|
|
153
|
+
"Generate a new route",
|
|
154
|
+
(yargs) => {
|
|
155
|
+
yargs.positional("name", {
|
|
156
|
+
describe: "Route name",
|
|
157
|
+
type: "string",
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
(argv) => {
|
|
161
|
+
const makeroute = require("./craft/commands/make-route.js");
|
|
162
|
+
makeroute(argv.name);
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
.command(
|
|
166
|
+
"make:service <name>",
|
|
167
|
+
"Generate a new service",
|
|
168
|
+
(yargs) => {
|
|
169
|
+
yargs.positional("name", {
|
|
170
|
+
describe: "Service name",
|
|
171
|
+
type: "string",
|
|
172
|
+
});
|
|
173
|
+
},
|
|
174
|
+
(argv) => {
|
|
175
|
+
const makeservice = require("./craft/commands/make-service.js");
|
|
176
|
+
makeservice(argv.name);
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
.command(
|
|
180
|
+
"make:test <name>",
|
|
181
|
+
"Generate a new unit test",
|
|
182
|
+
(yargs) => {
|
|
183
|
+
yargs.positional("name", {
|
|
184
|
+
describe: "Test name",
|
|
185
|
+
type: "string",
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
(argv) => {
|
|
189
|
+
const maketest = require("./craft/commands/make-test.js");
|
|
190
|
+
maketest(argv.name);
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
.command(
|
|
194
|
+
"make:utils <name>",
|
|
195
|
+
"Generate a new utils",
|
|
196
|
+
(yargs) => {
|
|
197
|
+
yargs.positional("name", {
|
|
198
|
+
describe: "Utils name",
|
|
199
|
+
type: "string",
|
|
200
|
+
});
|
|
201
|
+
},
|
|
202
|
+
(argv) => {
|
|
203
|
+
const makeutils = require("./craft/commands/make-utils.js");
|
|
204
|
+
makeutils(argv.name);
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
.command(
|
|
208
|
+
"make:validation <name>",
|
|
209
|
+
"Generate a new validation",
|
|
210
|
+
(yargs) => {
|
|
211
|
+
yargs.positional("name", {
|
|
212
|
+
describe: "Validation name",
|
|
213
|
+
type: "string",
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
(argv) => {
|
|
217
|
+
const makevalidation = require("./craft/commands/make-validation.js");
|
|
218
|
+
makevalidation(argv.name);
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
.command(
|
|
222
|
+
"make:view <name>",
|
|
223
|
+
"Generate a new view",
|
|
224
|
+
(yargs) => {
|
|
225
|
+
yargs.positional("name", {
|
|
226
|
+
describe: "View name",
|
|
227
|
+
type: "string",
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
(argv) => {
|
|
231
|
+
const makeview = require("./craft/commands/make-view.js");
|
|
232
|
+
makeview(argv.name);
|
|
233
|
+
}
|
|
234
|
+
)
|
|
235
|
+
.command(
|
|
236
|
+
"start",
|
|
237
|
+
"Starting production server",
|
|
238
|
+
() => {},
|
|
239
|
+
() => {
|
|
240
|
+
const start = require("./craft/commands/start.js");
|
|
241
|
+
start();
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
.command(
|
|
245
|
+
"test",
|
|
246
|
+
"Run Jest unit tests",
|
|
247
|
+
() => {},
|
|
248
|
+
() => {
|
|
249
|
+
const runtest = require("./craft/commands/test.js");
|
|
250
|
+
runtest();
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
.demandCommand()
|
|
254
|
+
.strict()
|
|
255
|
+
.help()
|
|
256
|
+
.parse();
|