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.
Files changed (66) hide show
  1. package/README.md +137 -0
  2. package/bin/index.js +158 -0
  3. package/package.json +24 -0
  4. package/template/.dockerignore +4 -0
  5. package/template/Dockerfile +12 -0
  6. package/template/babel.config.json +3 -0
  7. package/template/craft/commands/build.js +15 -0
  8. package/template/craft/commands/db-fresh.js +22 -0
  9. package/template/craft/commands/db-generate.js +23 -0
  10. package/template/craft/commands/db-migrate.js +22 -0
  11. package/template/craft/commands/dev.js +16 -0
  12. package/template/craft/commands/key-generate.js +41 -0
  13. package/template/craft/commands/make-apidocs.js +121 -0
  14. package/template/craft/commands/make-command.js +38 -0
  15. package/template/craft/commands/make-dto.js +39 -0
  16. package/template/craft/commands/make-middleware.js +46 -0
  17. package/template/craft/commands/make-repository.js +36 -0
  18. package/template/craft/commands/make-route.js +88 -0
  19. package/template/craft/commands/make-service.js +39 -0
  20. package/template/craft/commands/make-test.js +48 -0
  21. package/template/craft/commands/make-utils.js +30 -0
  22. package/template/craft/commands/make-validation.js +42 -0
  23. package/template/craft/commands/make-view.js +42 -0
  24. package/template/craft/commands/start.js +29 -0
  25. package/template/craft/commands/test.js +20 -0
  26. package/template/craft.js +256 -0
  27. package/template/nodemon.json +6 -0
  28. package/template/package-lock.json +8777 -0
  29. package/template/package.json +79 -0
  30. package/template/prisma/migrations/20250518142257_create_table_users/migration.sql +13 -0
  31. package/template/prisma/migrations/migration_lock.toml +3 -0
  32. package/template/prisma/schema.prisma +22 -0
  33. package/template/prisma/seed.ts +29 -0
  34. package/template/public/assets/images/default-user.png +0 -0
  35. package/template/src/apidocs/auth-docs.ts +314 -0
  36. package/template/src/apidocs/users-docs.ts +240 -0
  37. package/template/src/config/database.ts +90 -0
  38. package/template/src/config/env.ts +29 -0
  39. package/template/src/config/logger.ts +116 -0
  40. package/template/src/config/web.ts +40 -0
  41. package/template/src/controllers/auth-controller.ts +88 -0
  42. package/template/src/controllers/user-controller.ts +79 -0
  43. package/template/src/dtos/list-dto.ts +12 -0
  44. package/template/src/dtos/user-dto.ts +57 -0
  45. package/template/src/main.ts +28 -0
  46. package/template/src/middleware/auth-middleware.ts +44 -0
  47. package/template/src/middleware/error-middleware.ts +27 -0
  48. package/template/src/middleware/http-logger-middleware.ts +31 -0
  49. package/template/src/repositories/user-repository.ts +75 -0
  50. package/template/src/routes/auth-route.ts +20 -0
  51. package/template/src/routes/main-route.ts +25 -0
  52. package/template/src/routes/user-route.ts +35 -0
  53. package/template/src/services/auth-service.ts +162 -0
  54. package/template/src/services/user-service.ts +102 -0
  55. package/template/src/types/type-request.ts +6 -0
  56. package/template/src/utils/async-handler.ts +9 -0
  57. package/template/src/utils/response-error.ts +10 -0
  58. package/template/src/utils/response.ts +60 -0
  59. package/template/src/utils/swagger.ts +135 -0
  60. package/template/src/utils/validation.ts +7 -0
  61. package/template/src/validations/user-validation.ts +127 -0
  62. package/template/src/views/index.ejs +6 -0
  63. package/template/src/views/layouts/main.ejs +14 -0
  64. package/template/src/views/partials/header.ejs +3 -0
  65. package/template/test/user.test.ts +16 -0
  66. package/template/tsconfig.json +13 -0
@@ -0,0 +1,127 @@
1
+ import { z, ZodType } from "zod";
2
+
3
+ export class UserValidation {
4
+ static readonly REGISTER: ZodType = z.object({
5
+ fullName: z.preprocess(
6
+ (v) => (v === null ? undefined : v),
7
+ z
8
+ .string({
9
+ required_error: "Nama Lengkap Wajib Diisi",
10
+ })
11
+ .min(1, { message: "Nama Lengkap Tidak Boleh Kosong" })
12
+ .max(100, { message: "Nama Lengkap Maksimal 100 Karakter" })
13
+ ),
14
+ email: z.preprocess(
15
+ (v) => (v === null ? undefined : v),
16
+ z
17
+ .string({
18
+ required_error: "Email Wajib Diisi",
19
+ })
20
+ .min(1, { message: "Email Tidak Boleh Kosong" })
21
+ .max(100, { message: "Email Maksimal 100 Karakter" })
22
+ .email({ message: "Format Email Tidak Valid" })
23
+ ),
24
+ password: z.preprocess(
25
+ (v) => (v === null ? undefined : v),
26
+ z
27
+ .string({
28
+ required_error: "Kata Sandi Wajib Diisi",
29
+ })
30
+ .min(8, { message: "Kata Sandi Minimal 8 Karakter" })
31
+ .max(100, { message: "Kata Sandi Maksimal 100 Karakter" })
32
+ ),
33
+ as: z.string().optional(),
34
+ });
35
+
36
+ static readonly CREATE: ZodType = z.object({
37
+ fullName: z.preprocess(
38
+ (v) => (v === null ? undefined : v),
39
+ z
40
+ .string({
41
+ required_error: "Nama Lengkap Wajib Diisi",
42
+ })
43
+ .min(1, { message: "Nama Lengkap Tidak Boleh Kosong" })
44
+ .max(100, { message: "Nama Lengkap Maksimal 100 Karakter" })
45
+ ),
46
+ email: z.preprocess(
47
+ (v) => (v === null ? undefined : v),
48
+ z
49
+ .string({
50
+ required_error: "Email Wajib Diisi",
51
+ })
52
+ .min(1, { message: "Email Tidak Boleh Kosong" })
53
+ .max(100, { message: "Email Maksimal 100 Karakter" })
54
+ .email({ message: "Format email tidak valid" })
55
+ ),
56
+ password: z.preprocess(
57
+ (v) => (v === null ? undefined : v),
58
+ z
59
+ .string({
60
+ required_error: "Kata Sandi Wajib Diisi",
61
+ })
62
+ .min(8, { message: "Kata Sandi Minimal 8 Karakter" })
63
+ .max(100, { message: "Kata Sandi Maksimal 100 Karakter" })
64
+ ),
65
+ });
66
+
67
+ static readonly LOGIN: ZodType = z.object({
68
+ email: z.preprocess(
69
+ (v) => (v === null ? undefined : v),
70
+ z
71
+ .string({
72
+ required_error: "Username Atau Email Wajib Diisi",
73
+ })
74
+ .min(1, { message: "Username Atau Email Tidak Boleh Kosong" })
75
+ .max(100, { message: "Username Atau Email Maksimal 100 Karakter" })
76
+ ),
77
+ password: z.preprocess(
78
+ (v) => (v === null ? undefined : v),
79
+ z
80
+ .string({
81
+ required_error: "Password Wajib Diisi",
82
+ })
83
+ .min(1, { message: "Password Minimal 1 Karakter" })
84
+ .max(100, { message: "Password Maksimal 100 Karakter" })
85
+ ),
86
+ redirect_url: z.preprocess(
87
+ (v) => (v === null ? undefined : v),
88
+ z
89
+ .string({
90
+ required_error: "Redirect URL Wajib Diisi",
91
+ })
92
+ .optional()
93
+ ),
94
+ rememberMe: z.boolean().default(false).optional(),
95
+ });
96
+
97
+ static readonly UPDATE: ZodType = z.object({
98
+ fullName: z
99
+ .string({
100
+ required_error: "Nama Lengkap Wajib Diisi",
101
+ })
102
+ .min(1, { message: "Nama Lengkap Tidak Boleh Kosong" })
103
+ .max(100, { message: "Nama Lengkap Maksimal 100 Karakter" }),
104
+ email: z
105
+ .string({
106
+ required_error: "Email Wajib Diisi",
107
+ })
108
+ .min(1, { message: "Email minimal 1 Karakter" })
109
+ .max(100, { message: "Email Maksimal 100 Karakter" })
110
+ .email({ message: "Format email tidak valid" })
111
+ .optional(),
112
+ password: z
113
+ .string({
114
+ required_error: "Password Wajib Diisi",
115
+ })
116
+ .min(8, { message: "Password minimal 8 Karakter" })
117
+ .max(500, { message: "Password Maksimal 500 Karakter" })
118
+ .optional(),
119
+ });
120
+
121
+ static readonly LIST: ZodType = z.object({
122
+ page: z.number().min(1).positive(),
123
+ take: z.number().min(1).positive(),
124
+ skip: z.number(),
125
+ name: z.string().optional(),
126
+ });
127
+ }
@@ -0,0 +1,6 @@
1
+ <h2 class="text-2xl font-bold mb-4">Welcome to CraftJS</h2>
2
+ <p class="text-lg">
3
+ starter kit backend framework powered by Express, TypeScript, EJS Engine, and
4
+ Prisma — designed for rapid development, simplicity, and scalability.
5
+ </p>
6
+ <a href="https://www.npmjs.com/package/@muhammadisa226/craftjs"></a>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title><%= title %></title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ </head>
9
+ <body class="bg-gray-50 text-gray-800">
10
+ <%- include("../partials/header") %>
11
+
12
+ <main class="p-6"><%- body %></main>
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ <header class="bg-blue-600 text-white p-4">
2
+ <h1 class="text-xl font-semibold">CraftJS</h1>
3
+ </header>
@@ -0,0 +1,16 @@
1
+ import supertest from "supertest";
2
+ import { web } from "../src/application/web";
3
+ import { logger } from "../src/application/logging";
4
+ describe("POST /api/users", () => {
5
+ it("should register new user", async () => {
6
+ const response = await supertest(web).post("/api/auth/register").send({
7
+ fullName: "test",
8
+ email: "testing@gmail.com",
9
+ password: "12345678",
10
+ });
11
+ logger.debug(response.body);
12
+ expect(response.status).toBe(201);
13
+ expect(response.body.data.fullName).toBe("test");
14
+ expect(response.body.data.email).toBe("testing@gmail.com");
15
+ });
16
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "include": ["src/**/*", "craft.js"],
3
+ "compilerOptions": {
4
+ "target": "es2016",
5
+ "module": "commonjs",
6
+ "moduleResolution": "Node",
7
+ "outDir": "./dist",
8
+ "esModuleInterop": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "strict": true,
11
+ "skipLibCheck": true
12
+ }
13
+ }