create-craftjs 1.0.4 → 1.0.6
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 +139 -137
- package/bin/index.js +158 -158
- package/package.json +24 -24
- package/template/Dockerfile +57 -12
- package/template/babel.config.json +3 -3
- package/template/craft/commands/build.js +16 -15
- package/template/craft/commands/db-fresh.js +22 -22
- package/template/craft/commands/db-generate.js +23 -23
- package/template/craft/commands/db-migrate.js +22 -22
- package/template/craft/commands/dev.js +16 -16
- package/template/craft/commands/key-generate.js +41 -41
- package/template/craft/commands/make-apidocs.js +121 -121
- package/template/craft/commands/make-command.js +38 -38
- package/template/craft/commands/make-controller.js +95 -95
- package/template/craft/commands/make-dto.js +39 -39
- package/template/craft/commands/make-middleware.js +46 -46
- package/template/craft/commands/make-repository.js +36 -36
- package/template/craft/commands/make-route.js +92 -92
- package/template/craft/commands/make-service.js +39 -39
- package/template/craft/commands/make-test.js +48 -48
- package/template/craft/commands/make-utils.js +30 -30
- package/template/craft/commands/make-validation.js +42 -42
- package/template/craft/commands/make-view.js +42 -42
- package/template/craft/commands/start.js +29 -29
- package/template/craft/commands/test.js +20 -20
- package/template/craft.js +256 -256
- package/template/docker-compose.yml +8 -0
- package/template/nodemon.json +6 -6
- package/template/package-lock.json +8877 -8877
- package/template/package.json +84 -84
- package/template/prisma/schema.prisma +22 -22
- package/template/prisma/seed.ts +29 -29
- package/template/src/apidocs/auth-docs.ts +314 -314
- package/template/src/apidocs/users-docs.ts +240 -240
- package/template/src/config/cloudinary.ts +21 -21
- package/template/src/config/database.ts +90 -90
- package/template/src/config/env.ts +67 -67
- package/template/src/config/logger.ts +139 -139
- package/template/src/config/nodemailer.ts +23 -23
- package/template/src/config/web.ts +47 -47
- package/template/src/controllers/auth-controller.ts +88 -88
- package/template/src/controllers/user-controller.ts +79 -79
- package/template/src/dtos/list-dto.ts +12 -12
- package/template/src/dtos/user-dto.ts +57 -57
- package/template/src/main.ts +28 -28
- package/template/src/middleware/auth-middleware.ts +44 -44
- package/template/src/middleware/error-middleware.ts +27 -27
- package/template/src/middleware/http-logger-middleware.ts +31 -31
- package/template/src/repositories/user-repository.ts +75 -75
- package/template/src/routes/auth-route.ts +20 -20
- package/template/src/routes/main-route.ts +25 -25
- package/template/src/routes/user-route.ts +35 -35
- package/template/src/services/auth-service.ts +162 -162
- package/template/src/services/user-service.ts +102 -102
- package/template/src/types/type-request.ts +6 -6
- package/template/src/utils/async-handler.ts +9 -9
- package/template/src/utils/response-error.ts +10 -10
- package/template/src/utils/response.ts +60 -60
- package/template/src/utils/swagger.ts +135 -135
- package/template/src/utils/validation.ts +7 -7
- package/template/src/validations/user-validation.ts +127 -127
- package/template/src/views/index.ejs +6 -6
- package/template/src/views/layouts/main.ejs +14 -14
- package/template/src/views/partials/header.ejs +3 -3
- package/template/test/user.test.ts +16 -16
- package/template/tsconfig.json +13 -13
- package/template/.dockerignore +0 -4
package/template/Dockerfile
CHANGED
|
@@ -1,12 +1,57 @@
|
|
|
1
|
-
FROM node:
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
RUN
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
FROM node:22-slim AS base
|
|
2
|
+
|
|
3
|
+
# Install timezone data
|
|
4
|
+
RUN apt-get update && apt-get install -y tzdata openssl
|
|
5
|
+
|
|
6
|
+
# Set timezone
|
|
7
|
+
ENV TZ=Asia/Jakarta
|
|
8
|
+
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|
9
|
+
|
|
10
|
+
WORKDIR /usr/src/app
|
|
11
|
+
|
|
12
|
+
# Create logs folder
|
|
13
|
+
RUN mkdir -p logs
|
|
14
|
+
|
|
15
|
+
# Install dependencies based on package-lock.json
|
|
16
|
+
COPY package*.json ./
|
|
17
|
+
RUN npm ci
|
|
18
|
+
|
|
19
|
+
# Copy source code
|
|
20
|
+
COPY . .
|
|
21
|
+
|
|
22
|
+
# Generate Prisma client
|
|
23
|
+
RUN npx prisma generate
|
|
24
|
+
|
|
25
|
+
# Generate key (sesuaikan dengan perintahmu)
|
|
26
|
+
RUN node craft key:generate
|
|
27
|
+
|
|
28
|
+
# Build project (jika ada)
|
|
29
|
+
RUN node craft build
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Build stage untuk copy hasil build
|
|
33
|
+
FROM base AS build
|
|
34
|
+
|
|
35
|
+
# Nothing extra, base sudah berisi semua
|
|
36
|
+
|
|
37
|
+
# Production image
|
|
38
|
+
FROM node:22-slim AS production
|
|
39
|
+
|
|
40
|
+
WORKDIR /usr/src/app
|
|
41
|
+
|
|
42
|
+
# Copy package files untuk install production dependencies
|
|
43
|
+
COPY package*.json ./
|
|
44
|
+
|
|
45
|
+
# Install production dependencies saja
|
|
46
|
+
RUN npm ci --omit=dev
|
|
47
|
+
|
|
48
|
+
# Copy hasil build dan file penting dari build stage
|
|
49
|
+
COPY --from=build /usr/src/app/build ./build
|
|
50
|
+
COPY --from=build /usr/src/app/node_modules/.prisma ./node_modules/.prisma
|
|
51
|
+
COPY --from=build /usr/src/app/prisma ./prisma
|
|
52
|
+
COPY --from=build /usr/src/app/.env ./
|
|
53
|
+
COPY --from=build /usr/src/app/logs ./build/logs
|
|
54
|
+
|
|
55
|
+
EXPOSE 3000
|
|
56
|
+
|
|
57
|
+
CMD ["node", "build/main.js"]
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
{
|
|
2
|
-
"presets": ["@babel/preset-env", "@babel/preset-typescript"]
|
|
3
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"presets": ["@babel/preset-env", "@babel/preset-typescript"]
|
|
3
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
const { execSync } = require("child_process");
|
|
2
|
-
const chalk = require("chalk");
|
|
3
|
-
function Build() {
|
|
4
|
-
console.log(chalk.blue("📦 Building project..."));
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
execSync("npx tsc && cp -r src/views
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
const { execSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
function Build() {
|
|
4
|
+
console.log(chalk.blue("📦 Building project..."));
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
execSync("npx tsc && cp -r src/views build/views", { stdio: "inherit" });
|
|
8
|
+
execSync("cp -r public build/public", { stdio: "inherit" });
|
|
9
|
+
console.log(chalk.green("✅ Build completed successfully."));
|
|
10
|
+
} catch (error) {
|
|
11
|
+
console.error(chalk.red("❌ Build failed."));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = Build;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
const { spawnSync } = require("child_process");
|
|
2
|
-
const chalk = require("chalk");
|
|
3
|
-
|
|
4
|
-
function DbReset() {
|
|
5
|
-
console.log(chalk.blue("🚀 Running prisma migrate reset..."));
|
|
6
|
-
|
|
7
|
-
const result = spawnSync("npx", ["prisma", "migrate", "reset"], {
|
|
8
|
-
stdio: "inherit",
|
|
9
|
-
shell: true,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
if (result.status !== 0) {
|
|
13
|
-
console.error(chalk.red("❌ Migrate reset failed."));
|
|
14
|
-
if (result.error) {
|
|
15
|
-
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
16
|
-
}
|
|
17
|
-
process.exit(result.status ?? 1);
|
|
18
|
-
} else {
|
|
19
|
-
console.log(chalk.green("✅ Migrate reset completed."));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
module.exports = DbReset;
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
|
|
4
|
+
function DbReset() {
|
|
5
|
+
console.log(chalk.blue("🚀 Running prisma migrate reset..."));
|
|
6
|
+
|
|
7
|
+
const result = spawnSync("npx", ["prisma", "migrate", "reset"], {
|
|
8
|
+
stdio: "inherit",
|
|
9
|
+
shell: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (result.status !== 0) {
|
|
13
|
+
console.error(chalk.red("❌ Migrate reset failed."));
|
|
14
|
+
if (result.error) {
|
|
15
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
16
|
+
}
|
|
17
|
+
process.exit(result.status ?? 1);
|
|
18
|
+
} else {
|
|
19
|
+
console.log(chalk.green("✅ Migrate reset completed."));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
module.exports = DbReset;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
const { spawnSync } = require("child_process");
|
|
2
|
-
const chalk = require("chalk");
|
|
3
|
-
|
|
4
|
-
function DbGenerate() {
|
|
5
|
-
console.log(chalk.blue("🚀 Running prisma generate..."));
|
|
6
|
-
|
|
7
|
-
const result = spawnSync("npx", ["prisma", "generate"], {
|
|
8
|
-
stdio: "inherit",
|
|
9
|
-
shell: true,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
if (result.status !== 0) {
|
|
13
|
-
console.error(chalk.red("❌ Generate failed."));
|
|
14
|
-
// Jika ada error, print detailnya
|
|
15
|
-
if (result.error) {
|
|
16
|
-
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
17
|
-
}
|
|
18
|
-
process.exit(result.status ?? 1);
|
|
19
|
-
} else {
|
|
20
|
-
console.log(chalk.green("✅ Prisma generate completed."));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
module.exports = DbGenerate;
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
|
|
4
|
+
function DbGenerate() {
|
|
5
|
+
console.log(chalk.blue("🚀 Running prisma generate..."));
|
|
6
|
+
|
|
7
|
+
const result = spawnSync("npx", ["prisma", "generate"], {
|
|
8
|
+
stdio: "inherit",
|
|
9
|
+
shell: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (result.status !== 0) {
|
|
13
|
+
console.error(chalk.red("❌ Generate failed."));
|
|
14
|
+
// Jika ada error, print detailnya
|
|
15
|
+
if (result.error) {
|
|
16
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
17
|
+
}
|
|
18
|
+
process.exit(result.status ?? 1);
|
|
19
|
+
} else {
|
|
20
|
+
console.log(chalk.green("✅ Prisma generate completed."));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
module.exports = DbGenerate;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
const { spawnSync } = require("child_process");
|
|
2
|
-
const chalk = require("chalk");
|
|
3
|
-
|
|
4
|
-
function DbMigrate() {
|
|
5
|
-
console.log(chalk.blue("🚀 Running prisma migrate dev..."));
|
|
6
|
-
|
|
7
|
-
const result = spawnSync("npx", ["prisma", "migrate", "dev"], {
|
|
8
|
-
stdio: "inherit",
|
|
9
|
-
shell: true,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
if (result.status !== 0) {
|
|
13
|
-
console.error(chalk.red("❌ Migration failed."));
|
|
14
|
-
if (result.error) {
|
|
15
|
-
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
16
|
-
}
|
|
17
|
-
process.exit(result.status ?? 1);
|
|
18
|
-
} else {
|
|
19
|
-
console.log(chalk.green("✅ Migration completed."));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
module.exports = DbMigrate;
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
|
|
4
|
+
function DbMigrate() {
|
|
5
|
+
console.log(chalk.blue("🚀 Running prisma migrate dev..."));
|
|
6
|
+
|
|
7
|
+
const result = spawnSync("npx", ["prisma", "migrate", "dev"], {
|
|
8
|
+
stdio: "inherit",
|
|
9
|
+
shell: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
if (result.status !== 0) {
|
|
13
|
+
console.error(chalk.red("❌ Migration failed."));
|
|
14
|
+
if (result.error) {
|
|
15
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
16
|
+
}
|
|
17
|
+
process.exit(result.status ?? 1);
|
|
18
|
+
} else {
|
|
19
|
+
console.log(chalk.green("✅ Migration completed."));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
module.exports = DbMigrate;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
const { spawnSync } = require("child_process");
|
|
2
|
-
const chalk = require("chalk");
|
|
3
|
-
|
|
4
|
-
function Dev() {
|
|
5
|
-
console.log(chalk.blue("🚀 Starting development server with nodemon..."));
|
|
6
|
-
const result = spawnSync("nodemon", ["./src/main.ts"], {
|
|
7
|
-
stdio: "inherit",
|
|
8
|
-
shell: true,
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
if (result.status !== 0) {
|
|
12
|
-
console.error(chalk.red("❌ Failed to start development server."));
|
|
13
|
-
process.exit(result.status ?? 1);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
module.exports = Dev;
|
|
1
|
+
const { spawnSync } = require("child_process");
|
|
2
|
+
const chalk = require("chalk");
|
|
3
|
+
|
|
4
|
+
function Dev() {
|
|
5
|
+
console.log(chalk.blue("🚀 Starting development server with nodemon..."));
|
|
6
|
+
const result = spawnSync("nodemon", ["./src/main.ts"], {
|
|
7
|
+
stdio: "inherit",
|
|
8
|
+
shell: true,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
if (result.status !== 0) {
|
|
12
|
+
console.error(chalk.red("❌ Failed to start development server."));
|
|
13
|
+
process.exit(result.status ?? 1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
module.exports = Dev;
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
const chalk = require("chalk");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const crypto = require("crypto");
|
|
5
|
-
|
|
6
|
-
function keyGenerate() {
|
|
7
|
-
const envPath = path.resolve(process.cwd(), ".env");
|
|
8
|
-
if (!fs.existsSync(envPath)) {
|
|
9
|
-
console.error(chalk.red("❌ .env file not found!"));
|
|
10
|
-
process.exit(1);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let envContent = fs.readFileSync(envPath, "utf-8");
|
|
14
|
-
|
|
15
|
-
const generateKey = (number) => crypto.randomBytes(number).toString("hex");
|
|
16
|
-
|
|
17
|
-
if (envContent.includes("JWT_SECRET=")) {
|
|
18
|
-
envContent = envContent.replace(
|
|
19
|
-
/JWT_SECRET=.*/g,
|
|
20
|
-
`JWT_SECRET=${generateKey(16)}`
|
|
21
|
-
);
|
|
22
|
-
} else {
|
|
23
|
-
envContent += `\nJWT_SECRET_ACCESS_TOKEN=${generateKey(16)}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (envContent.includes("APP_SECRET=")) {
|
|
27
|
-
envContent = envContent.replace(
|
|
28
|
-
/APP_SECRET=.*/g,
|
|
29
|
-
`APP_SECRET=${generateKey(32)}`
|
|
30
|
-
);
|
|
31
|
-
} else {
|
|
32
|
-
envContent += `\APP_SECRET=${generateKey(32)}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
fs.writeFileSync(envPath, envContent);
|
|
36
|
-
|
|
37
|
-
console.log(
|
|
38
|
-
chalk.green("✅ App Secret and JWT Secret generated successfully.")
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
module.exports = keyGenerate;
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const crypto = require("crypto");
|
|
5
|
+
|
|
6
|
+
function keyGenerate() {
|
|
7
|
+
const envPath = path.resolve(process.cwd(), ".env");
|
|
8
|
+
if (!fs.existsSync(envPath)) {
|
|
9
|
+
console.error(chalk.red("❌ .env file not found!"));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let envContent = fs.readFileSync(envPath, "utf-8");
|
|
14
|
+
|
|
15
|
+
const generateKey = (number) => crypto.randomBytes(number).toString("hex");
|
|
16
|
+
|
|
17
|
+
if (envContent.includes("JWT_SECRET=")) {
|
|
18
|
+
envContent = envContent.replace(
|
|
19
|
+
/JWT_SECRET=.*/g,
|
|
20
|
+
`JWT_SECRET=${generateKey(16)}`
|
|
21
|
+
);
|
|
22
|
+
} else {
|
|
23
|
+
envContent += `\nJWT_SECRET_ACCESS_TOKEN=${generateKey(16)}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (envContent.includes("APP_SECRET=")) {
|
|
27
|
+
envContent = envContent.replace(
|
|
28
|
+
/APP_SECRET=.*/g,
|
|
29
|
+
`APP_SECRET=${generateKey(32)}`
|
|
30
|
+
);
|
|
31
|
+
} else {
|
|
32
|
+
envContent += `\APP_SECRET=${generateKey(32)}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fs.writeFileSync(envPath, envContent);
|
|
36
|
+
|
|
37
|
+
console.log(
|
|
38
|
+
chalk.green("✅ App Secret and JWT Secret generated successfully.")
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
module.exports = keyGenerate;
|
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const chalk = require("chalk");
|
|
4
|
-
|
|
5
|
-
function makeApiDocs(name) {
|
|
6
|
-
if (!name) {
|
|
7
|
-
console.log(chalk.red("❌ Please provide a apidocs name."));
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const fileName = `${name.toLowerCase()}-docs.ts`;
|
|
12
|
-
const targetDir = path.resolve("src", "apidocs");
|
|
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("⚠️ Apidocs already exists."));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const content = `/**
|
|
25
|
-
* @swagger
|
|
26
|
-
* /api/${name}:
|
|
27
|
-
* get:
|
|
28
|
-
* summary: Mengambil daftar semua ${name}
|
|
29
|
-
* tags: [${name}s]
|
|
30
|
-
* security:
|
|
31
|
-
* - bearerAuth: []
|
|
32
|
-
* parameters:
|
|
33
|
-
* - in: query
|
|
34
|
-
* name: page
|
|
35
|
-
* schema:
|
|
36
|
-
* type: integer
|
|
37
|
-
* required: false
|
|
38
|
-
* description: Nomor halaman
|
|
39
|
-
* - in: query
|
|
40
|
-
* name: take
|
|
41
|
-
* schema:
|
|
42
|
-
* type: integer
|
|
43
|
-
* required: false
|
|
44
|
-
* description: Jumlah data per halaman
|
|
45
|
-
* - in: query
|
|
46
|
-
* name: name
|
|
47
|
-
* schema:
|
|
48
|
-
* type: string
|
|
49
|
-
* required: false
|
|
50
|
-
* description: Filter berdasarkan nama (fullName)
|
|
51
|
-
* responses:
|
|
52
|
-
* 200:
|
|
53
|
-
* description: Berhasil Get All Data
|
|
54
|
-
* content:
|
|
55
|
-
* application/json:
|
|
56
|
-
* schema:
|
|
57
|
-
* type: object
|
|
58
|
-
* properties:
|
|
59
|
-
* status:
|
|
60
|
-
* type: boolean
|
|
61
|
-
* status_code:
|
|
62
|
-
* type: integer
|
|
63
|
-
* message:
|
|
64
|
-
* type: string
|
|
65
|
-
* data:
|
|
66
|
-
* type: object
|
|
67
|
-
* properties:
|
|
68
|
-
* data:
|
|
69
|
-
* type: array
|
|
70
|
-
* items:
|
|
71
|
-
* type: object
|
|
72
|
-
* properties:
|
|
73
|
-
* id:
|
|
74
|
-
* type: string
|
|
75
|
-
* format: uuid
|
|
76
|
-
* fullName:
|
|
77
|
-
* type: string
|
|
78
|
-
* email:
|
|
79
|
-
* type: string
|
|
80
|
-
* username:
|
|
81
|
-
* type: string
|
|
82
|
-
* password:
|
|
83
|
-
* type: string
|
|
84
|
-
* description: (Hashed password)
|
|
85
|
-
* image_id:
|
|
86
|
-
* type: string
|
|
87
|
-
* image_url:
|
|
88
|
-
* type: string
|
|
89
|
-
* format: uri
|
|
90
|
-
* is_verify:
|
|
91
|
-
* type: boolean
|
|
92
|
-
* created_at:
|
|
93
|
-
* type: string
|
|
94
|
-
* format: date-time
|
|
95
|
-
* updated_at:
|
|
96
|
-
* type: string
|
|
97
|
-
* format: date-time
|
|
98
|
-
* deleted_at:
|
|
99
|
-
* type: string
|
|
100
|
-
* format: date-time
|
|
101
|
-
* nullable: true
|
|
102
|
-
* role_id:
|
|
103
|
-
* type: string
|
|
104
|
-
* format: uuid
|
|
105
|
-
* total_data:
|
|
106
|
-
* type: integer
|
|
107
|
-
* paging:
|
|
108
|
-
* type: object
|
|
109
|
-
* properties:
|
|
110
|
-
* current_page:
|
|
111
|
-
* type: integer
|
|
112
|
-
* total_page:
|
|
113
|
-
* type: integer
|
|
114
|
-
|
|
115
|
-
*/
|
|
116
|
-
`;
|
|
117
|
-
|
|
118
|
-
fs.writeFileSync(filePath, content);
|
|
119
|
-
console.log(chalk.green(`✅ Controller created at ${filePath}`));
|
|
120
|
-
}
|
|
121
|
-
module.exports = makeApiDocs;
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
|
|
5
|
+
function makeApiDocs(name) {
|
|
6
|
+
if (!name) {
|
|
7
|
+
console.log(chalk.red("❌ Please provide a apidocs name."));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const fileName = `${name.toLowerCase()}-docs.ts`;
|
|
12
|
+
const targetDir = path.resolve("src", "apidocs");
|
|
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("⚠️ Apidocs already exists."));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const content = `/**
|
|
25
|
+
* @swagger
|
|
26
|
+
* /api/${name}:
|
|
27
|
+
* get:
|
|
28
|
+
* summary: Mengambil daftar semua ${name}
|
|
29
|
+
* tags: [${name}s]
|
|
30
|
+
* security:
|
|
31
|
+
* - bearerAuth: []
|
|
32
|
+
* parameters:
|
|
33
|
+
* - in: query
|
|
34
|
+
* name: page
|
|
35
|
+
* schema:
|
|
36
|
+
* type: integer
|
|
37
|
+
* required: false
|
|
38
|
+
* description: Nomor halaman
|
|
39
|
+
* - in: query
|
|
40
|
+
* name: take
|
|
41
|
+
* schema:
|
|
42
|
+
* type: integer
|
|
43
|
+
* required: false
|
|
44
|
+
* description: Jumlah data per halaman
|
|
45
|
+
* - in: query
|
|
46
|
+
* name: name
|
|
47
|
+
* schema:
|
|
48
|
+
* type: string
|
|
49
|
+
* required: false
|
|
50
|
+
* description: Filter berdasarkan nama (fullName)
|
|
51
|
+
* responses:
|
|
52
|
+
* 200:
|
|
53
|
+
* description: Berhasil Get All Data
|
|
54
|
+
* content:
|
|
55
|
+
* application/json:
|
|
56
|
+
* schema:
|
|
57
|
+
* type: object
|
|
58
|
+
* properties:
|
|
59
|
+
* status:
|
|
60
|
+
* type: boolean
|
|
61
|
+
* status_code:
|
|
62
|
+
* type: integer
|
|
63
|
+
* message:
|
|
64
|
+
* type: string
|
|
65
|
+
* data:
|
|
66
|
+
* type: object
|
|
67
|
+
* properties:
|
|
68
|
+
* data:
|
|
69
|
+
* type: array
|
|
70
|
+
* items:
|
|
71
|
+
* type: object
|
|
72
|
+
* properties:
|
|
73
|
+
* id:
|
|
74
|
+
* type: string
|
|
75
|
+
* format: uuid
|
|
76
|
+
* fullName:
|
|
77
|
+
* type: string
|
|
78
|
+
* email:
|
|
79
|
+
* type: string
|
|
80
|
+
* username:
|
|
81
|
+
* type: string
|
|
82
|
+
* password:
|
|
83
|
+
* type: string
|
|
84
|
+
* description: (Hashed password)
|
|
85
|
+
* image_id:
|
|
86
|
+
* type: string
|
|
87
|
+
* image_url:
|
|
88
|
+
* type: string
|
|
89
|
+
* format: uri
|
|
90
|
+
* is_verify:
|
|
91
|
+
* type: boolean
|
|
92
|
+
* created_at:
|
|
93
|
+
* type: string
|
|
94
|
+
* format: date-time
|
|
95
|
+
* updated_at:
|
|
96
|
+
* type: string
|
|
97
|
+
* format: date-time
|
|
98
|
+
* deleted_at:
|
|
99
|
+
* type: string
|
|
100
|
+
* format: date-time
|
|
101
|
+
* nullable: true
|
|
102
|
+
* role_id:
|
|
103
|
+
* type: string
|
|
104
|
+
* format: uuid
|
|
105
|
+
* total_data:
|
|
106
|
+
* type: integer
|
|
107
|
+
* paging:
|
|
108
|
+
* type: object
|
|
109
|
+
* properties:
|
|
110
|
+
* current_page:
|
|
111
|
+
* type: integer
|
|
112
|
+
* total_page:
|
|
113
|
+
* type: integer
|
|
114
|
+
|
|
115
|
+
*/
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
fs.writeFileSync(filePath, content);
|
|
119
|
+
console.log(chalk.green(`✅ Controller created at ${filePath}`));
|
|
120
|
+
}
|
|
121
|
+
module.exports = makeApiDocs;
|