@skalfa/skalfa-api-core 1.0.2 → 1.0.7

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 (272) hide show
  1. package/CONTRIBUTING.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +60 -0
  4. package/dist/auth/auth.d.ts +18 -15
  5. package/dist/auth/auth.js +20 -203
  6. package/dist/auth/auth.js.map +1 -1
  7. package/dist/auth/create-access-token.d.ts +4 -0
  8. package/dist/auth/create-access-token.js +26 -0
  9. package/dist/auth/create-access-token.js.map +1 -0
  10. package/dist/auth/create-user-mail-token.d.ts +4 -0
  11. package/dist/auth/create-user-mail-token.js +19 -0
  12. package/dist/auth/create-user-mail-token.js.map +1 -0
  13. package/dist/auth/helpers/generate-agent-id.d.ts +1 -0
  14. package/dist/auth/helpers/generate-agent-id.js +7 -0
  15. package/dist/auth/helpers/generate-agent-id.js.map +1 -0
  16. package/dist/auth/helpers/get-request-ip.d.ts +1 -0
  17. package/dist/auth/helpers/get-request-ip.js +4 -0
  18. package/dist/auth/helpers/get-request-ip.js.map +1 -0
  19. package/dist/auth/helpers/get-user-permissions.d.ts +1 -0
  20. package/dist/auth/helpers/get-user-permissions.js +9 -0
  21. package/dist/auth/helpers/get-user-permissions.js.map +1 -0
  22. package/dist/auth/helpers/index.d.ts +3 -0
  23. package/dist/auth/helpers/index.js +4 -0
  24. package/dist/auth/helpers/index.js.map +1 -0
  25. package/dist/auth/list-user-sessions.d.ts +1 -0
  26. package/dist/auth/list-user-sessions.js +10 -0
  27. package/dist/auth/list-user-sessions.js.map +1 -0
  28. package/dist/auth/revalidate-user-permissions-by-role.d.ts +1 -0
  29. package/dist/auth/revalidate-user-permissions-by-role.js +12 -0
  30. package/dist/auth/revalidate-user-permissions-by-role.js.map +1 -0
  31. package/dist/auth/revalidate-user-permissions.d.ts +1 -0
  32. package/dist/auth/revalidate-user-permissions.js +21 -0
  33. package/dist/auth/revalidate-user-permissions.js.map +1 -0
  34. package/dist/auth/revoke-access-token.d.ts +1 -0
  35. package/dist/auth/revoke-access-token.js +5 -0
  36. package/dist/auth/revoke-access-token.js.map +1 -0
  37. package/dist/auth/verify-access-token.d.ts +1 -0
  38. package/dist/auth/verify-access-token.js +47 -0
  39. package/dist/auth/verify-access-token.js.map +1 -0
  40. package/dist/auth/verify-user-mail-token.d.ts +1 -0
  41. package/dist/auth/verify-user-mail-token.js +21 -0
  42. package/dist/auth/verify-user-mail-token.js.map +1 -0
  43. package/dist/commands/cli.js +5 -3
  44. package/dist/commands/cli.js.map +1 -1
  45. package/dist/commands/make/basic-controller.js +1 -1
  46. package/dist/commands/make/basic-controller.js.map +1 -1
  47. package/dist/commands/make/basic-migration.d.ts +1 -1
  48. package/dist/commands/make/basic-migration.js +2 -2
  49. package/dist/commands/make/basic-migration.js.map +1 -1
  50. package/dist/commands/make/basic-model.js +1 -1
  51. package/dist/commands/make/basic-model.js.map +1 -1
  52. package/dist/commands/make/basic-seeder.js +1 -1
  53. package/dist/commands/make/basic-seeder.js.map +1 -1
  54. package/dist/commands/make/blueprint.js +1 -1
  55. package/dist/commands/make/blueprint.js.map +1 -1
  56. package/dist/commands/make/da-migration.js +3 -3
  57. package/dist/commands/make/da-migration.js.map +1 -1
  58. package/dist/commands/make/mail.js +2 -2
  59. package/dist/commands/make/mail.js.map +1 -1
  60. package/dist/commands/make/notification.js +1 -1
  61. package/dist/commands/make/notification.js.map +1 -1
  62. package/dist/commands/make/queue.js +1 -1
  63. package/dist/commands/make/queue.js.map +1 -1
  64. package/dist/commands/make/resource.d.ts +2 -0
  65. package/dist/commands/make/resource.js +19 -0
  66. package/dist/commands/make/resource.js.map +1 -0
  67. package/dist/commands/make/{light-controller.js → skalfa-controller.js} +3 -3
  68. package/dist/commands/make/skalfa-controller.js.map +1 -0
  69. package/dist/commands/make/{light-model.js → skalfa-model.js} +4 -4
  70. package/dist/commands/make/skalfa-model.js.map +1 -0
  71. package/dist/commands/runner/barrels.js.map +1 -1
  72. package/dist/commands/runner/blueprint/controller-generation.js.map +1 -1
  73. package/dist/commands/runner/blueprint/documentation-generation.js.map +1 -1
  74. package/dist/commands/runner/blueprint/migration-generation.js +1 -1
  75. package/dist/commands/runner/blueprint/migration-generation.js.map +1 -1
  76. package/dist/commands/runner/blueprint/model-generation.js.map +1 -1
  77. package/dist/commands/runner/blueprint/runner.js +2 -2
  78. package/dist/commands/runner/blueprint/runner.js.map +1 -1
  79. package/dist/commands/runner/blueprint/seeder-generation.js +1 -1
  80. package/dist/commands/runner/blueprint/seeder-generation.js.map +1 -1
  81. package/dist/commands/runner/da-migration.js +1 -2
  82. package/dist/commands/runner/da-migration.js.map +1 -1
  83. package/dist/commands/runner/migration.js +1 -1
  84. package/dist/commands/runner/migration.js.map +1 -1
  85. package/dist/commands/runner/seeder.js +1 -1
  86. package/dist/commands/runner/seeder.js.map +1 -1
  87. package/dist/context/context.js +6 -0
  88. package/dist/context/context.js.map +1 -1
  89. package/dist/controller/controller.d.ts +17 -30
  90. package/dist/controller/controller.js +39 -121
  91. package/dist/controller/controller.js.map +1 -1
  92. package/dist/controller/response.d.ts +6 -0
  93. package/dist/controller/response.js +63 -0
  94. package/dist/controller/response.js.map +1 -0
  95. package/dist/controller/storage.d.ts +9 -0
  96. package/dist/controller/storage.js +56 -0
  97. package/dist/controller/storage.js.map +1 -0
  98. package/dist/conversion/conversion.d.ts +3 -0
  99. package/dist/conversion/conversion.js +28 -4
  100. package/dist/conversion/conversion.js.map +1 -1
  101. package/dist/conversion/date.d.ts +1 -0
  102. package/dist/conversion/date.js +77 -0
  103. package/dist/conversion/date.js.map +1 -0
  104. package/dist/index.d.ts +2 -0
  105. package/dist/index.js +2 -0
  106. package/dist/index.js.map +1 -1
  107. package/dist/logger/logger.js +33 -0
  108. package/dist/logger/logger.js.map +1 -1
  109. package/dist/mail/mail.js +6 -6
  110. package/dist/mail/mail.js.map +1 -1
  111. package/dist/middleware/access-log.d.ts +31 -0
  112. package/dist/middleware/access-log.js +13 -0
  113. package/dist/middleware/access-log.js.map +1 -0
  114. package/dist/middleware/auth.d.ts +37 -0
  115. package/dist/middleware/auth.js +16 -0
  116. package/dist/middleware/auth.js.map +1 -0
  117. package/dist/middleware/body-parse.d.ts +35 -0
  118. package/dist/middleware/body-parse.js +87 -0
  119. package/dist/middleware/body-parse.js.map +1 -0
  120. package/dist/middleware/context.d.ts +29 -0
  121. package/dist/middleware/context.js +8 -0
  122. package/dist/middleware/context.js.map +1 -0
  123. package/dist/middleware/cors.d.ts +31 -0
  124. package/dist/middleware/cors.js +27 -0
  125. package/dist/middleware/cors.js.map +1 -0
  126. package/dist/middleware/error-handler.d.ts +33 -0
  127. package/dist/middleware/error-handler.js +17 -0
  128. package/dist/middleware/error-handler.js.map +1 -0
  129. package/dist/middleware/middleware.d.ts +31 -10
  130. package/dist/middleware/middleware.js +41 -209
  131. package/dist/middleware/middleware.js.map +1 -1
  132. package/dist/middleware/private.d.ts +29 -0
  133. package/dist/middleware/private.js +8 -0
  134. package/dist/middleware/private.js.map +1 -0
  135. package/dist/middleware/rate-limiter.d.ts +32 -0
  136. package/dist/middleware/rate-limiter.js +30 -0
  137. package/dist/middleware/rate-limiter.js.map +1 -0
  138. package/dist/notification/index.d.ts +1 -0
  139. package/dist/notification/index.js +2 -0
  140. package/dist/notification/index.js.map +1 -0
  141. package/dist/notification/notification.d.ts +16 -0
  142. package/dist/notification/notification.js +64 -0
  143. package/dist/notification/notification.js.map +1 -0
  144. package/dist/permission/permission.js +9 -0
  145. package/dist/permission/permission.js.map +1 -1
  146. package/dist/registry/registry.d.ts +0 -6
  147. package/dist/registry/registry.js +6 -6
  148. package/dist/registry/registry.js.map +1 -1
  149. package/dist/storage/storage.d.ts +3 -3
  150. package/dist/storage/storage.js.map +1 -1
  151. package/dist/validation/validation.js +43 -51
  152. package/dist/validation/validation.js.map +1 -1
  153. package/package.json +4 -4
  154. package/src/auth/auth.ts +21 -252
  155. package/src/auth/create-access-token.ts +29 -0
  156. package/src/auth/create-user-mail-token.ts +24 -0
  157. package/src/auth/helpers/generate-agent-id.ts +8 -0
  158. package/src/auth/helpers/get-request-ip.ts +3 -0
  159. package/src/auth/helpers/get-user-permissions.ts +15 -0
  160. package/src/auth/helpers/index.ts +3 -0
  161. package/src/auth/list-user-sessions.ts +11 -0
  162. package/src/auth/revalidate-user-permissions-by-role.ts +13 -0
  163. package/src/auth/revalidate-user-permissions.ts +26 -0
  164. package/src/auth/revoke-access-token.ts +5 -0
  165. package/src/auth/verify-access-token.ts +56 -0
  166. package/src/auth/verify-user-mail-token.ts +24 -0
  167. package/src/commands/cli.ts +5 -3
  168. package/src/commands/make/basic-controller.ts +3 -1
  169. package/src/commands/make/basic-migration.ts +5 -3
  170. package/src/commands/make/basic-model.ts +3 -1
  171. package/src/commands/make/basic-seeder.ts +3 -1
  172. package/src/commands/make/blueprint.ts +3 -1
  173. package/src/commands/make/da-migration.ts +6 -5
  174. package/src/commands/make/mail.ts +4 -2
  175. package/src/commands/make/notification.ts +3 -1
  176. package/src/commands/make/queue.ts +3 -1
  177. package/src/commands/make/resource.ts +21 -0
  178. package/src/commands/make/{light-controller.ts → skalfa-controller.ts} +4 -2
  179. package/src/commands/make/{light-model.ts → skalfa-model.ts} +5 -3
  180. package/src/commands/runner/barrels.ts +4 -0
  181. package/src/commands/runner/blueprint/controller-generation.ts +2 -0
  182. package/src/commands/runner/blueprint/documentation-generation.ts +2 -0
  183. package/src/commands/runner/blueprint/migration-generation.ts +3 -1
  184. package/src/commands/runner/blueprint/model-generation.ts +2 -0
  185. package/src/commands/runner/blueprint/runner.ts +10 -2
  186. package/src/commands/runner/blueprint/seeder-generation.ts +3 -1
  187. package/src/commands/runner/da-migration.ts +3 -2
  188. package/src/commands/runner/migration.ts +1 -1
  189. package/src/commands/runner/seeder.ts +1 -1
  190. package/src/context/context.ts +23 -17
  191. package/src/controller/controller.ts +124 -239
  192. package/src/controller/response.ts +78 -0
  193. package/src/controller/storage.ts +78 -0
  194. package/src/conversion/conversion.ts +90 -64
  195. package/src/conversion/date.ts +74 -0
  196. package/src/index.ts +2 -0
  197. package/src/logger/logger.ts +217 -176
  198. package/src/mail/mail.ts +85 -85
  199. package/src/middleware/access-log.ts +15 -0
  200. package/src/middleware/auth.ts +19 -0
  201. package/src/middleware/body-parse.ts +83 -0
  202. package/src/middleware/context.ts +11 -0
  203. package/src/middleware/cors.ts +31 -0
  204. package/src/middleware/error-handler.ts +20 -0
  205. package/src/middleware/middleware.ts +91 -288
  206. package/src/middleware/private.ts +8 -0
  207. package/src/middleware/rate-limiter.ts +41 -0
  208. package/src/notification/index.ts +1 -0
  209. package/src/notification/notification.ts +86 -0
  210. package/src/permission/permission.ts +140 -136
  211. package/src/registry/registry.ts +17 -15
  212. package/src/route/route.ts +11 -11
  213. package/src/storage/storage.ts +104 -106
  214. package/src/validation/validation.ts +322 -346
  215. package/dist/auth.util.d.ts +0 -19
  216. package/dist/auth.util.js +0 -183
  217. package/dist/auth.util.js.map +0 -1
  218. package/dist/commands/make/light-controller.js.map +0 -1
  219. package/dist/commands/make/light-model.js.map +0 -1
  220. package/dist/context.util.d.ts +0 -7
  221. package/dist/context.util.js +0 -11
  222. package/dist/context.util.js.map +0 -1
  223. package/dist/controller.util.d.ts +0 -118
  224. package/dist/controller.util.js +0 -144
  225. package/dist/controller.util.js.map +0 -1
  226. package/dist/conversion.util.d.ts +0 -8
  227. package/dist/conversion.util.js +0 -52
  228. package/dist/conversion.util.js.map +0 -1
  229. package/dist/db/db.d.ts +0 -84
  230. package/dist/db/db.js +0 -177
  231. package/dist/db/db.js.map +0 -1
  232. package/dist/db/index.d.ts +0 -1
  233. package/dist/db/index.js +0 -2
  234. package/dist/db/index.js.map +0 -1
  235. package/dist/db.util.d.ts +0 -84
  236. package/dist/db.util.js +0 -177
  237. package/dist/db.util.js.map +0 -1
  238. package/dist/logger.util.d.ts +0 -30
  239. package/dist/logger.util.js +0 -126
  240. package/dist/logger.util.js.map +0 -1
  241. package/dist/mail.util.d.ts +0 -21
  242. package/dist/mail.util.js +0 -53
  243. package/dist/mail.util.js.map +0 -1
  244. package/dist/middleware.util.d.ts +0 -263
  245. package/dist/middleware.util.js +0 -233
  246. package/dist/middleware.util.js.map +0 -1
  247. package/dist/model/index.d.ts +0 -3
  248. package/dist/model/index.js +0 -4
  249. package/dist/model/index.js.map +0 -1
  250. package/dist/model/model.d.ts +0 -204
  251. package/dist/model/model.js +0 -1495
  252. package/dist/model/model.js.map +0 -1
  253. package/dist/model.util.d.ts +0 -204
  254. package/dist/model.util.js +0 -1495
  255. package/dist/model.util.js.map +0 -1
  256. package/dist/permission.util.d.ts +0 -38
  257. package/dist/permission.util.js +0 -91
  258. package/dist/permission.util.js.map +0 -1
  259. package/dist/registry.util.d.ts +0 -28
  260. package/dist/registry.util.js +0 -19
  261. package/dist/registry.util.js.map +0 -1
  262. package/dist/route.util.d.ts +0 -1
  263. package/dist/route.util.js +0 -12
  264. package/dist/route.util.js.map +0 -1
  265. package/dist/storage.util.d.ts +0 -56
  266. package/dist/storage.util.js +0 -82
  267. package/dist/storage.util.js.map +0 -1
  268. package/dist/validation.util.d.ts +0 -7
  269. package/dist/validation.util.js +0 -237
  270. package/dist/validation.util.js.map +0 -1
  271. /package/dist/commands/make/{light-controller.d.ts → skalfa-controller.d.ts} +0 -0
  272. /package/dist/commands/make/{light-model.d.ts → skalfa-model.d.ts} +0 -0
@@ -1,65 +1,91 @@
1
- export const conversion = {
2
-
3
- // =============================>
4
- // ## Conversion: String formatter
5
- // =============================>
6
- strSnake(value: string, delimiter: string = "_"): string {
7
- return toWords(value).join(delimiter)
8
- },
9
-
10
- strSlug(value: string, delimiter: string = "-"): string {
11
- return toWords(value).join(delimiter);
12
- },
13
-
14
- strCamel(value: string, delimiter: string = ""): string {
15
- return toWords(value).map((w, i) => i === 0 ? w : w[0].toUpperCase() + w.slice(1)).join(delimiter);
16
- },
17
-
18
- strPascal(value: string, delimiter: string = ""): string {
19
- return toWords(value).map(w => w[0].toUpperCase() + w.slice(1)).join(delimiter);
20
- },
21
-
22
- strPlural(value: string): string {
23
- const match = value.match(/^(.*?)([A-Za-z]+)$/)
24
- if (!match) return value
25
-
26
- const [, prefix, word] = match
27
-
28
- if (word.endsWith("y") && !/[aeiou]y$/i.test(word)) {
29
- return prefix + word.slice(0, -1) + "ies"
30
- }
31
-
32
- if (!word.endsWith("s")) return prefix + word + "s"
33
-
34
- return value
35
- },
36
-
37
- strSingular(value: string): string {
38
- const match = value.match(/^(.*?)([A-Za-z]+)$/)
39
- if (!match) return value
40
-
41
- const [, prefix, word] = match
42
-
43
- if (word.endsWith("ies")) {
44
- return prefix + word.slice(0, -3) + "y"
45
- }
46
-
47
- if (word.endsWith("s") && !word.endsWith("ss")) {
48
- return prefix + word.slice(0, -1)
49
- }
50
-
51
- return value
52
- }
53
- };
54
-
55
-
56
-
57
- function toWords(value: string): string[] {
58
- return value
59
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
60
- .replace(/[_\-\s]+/g, " ")
61
- .trim()
62
- .toLowerCase()
63
- .split(" ")
64
- .filter(Boolean)
1
+ import { date } from './date'
2
+
3
+ export const conversion = {
4
+ // =====================================>
5
+ // ## Conversion: format string to snake case
6
+ // =====================================>
7
+ strSnake(value: string, delimiter: string = "_"): string {
8
+ return toWords(value).join(delimiter)
9
+ },
10
+
11
+ // =====================================>
12
+ // ## Conversion: format string to slug
13
+ // =====================================>
14
+ strSlug(value: string, delimiter: string = "-"): string {
15
+ return toWords(value).join(delimiter);
16
+ },
17
+
18
+ // =====================================>
19
+ // ## Conversion: format string to camel case
20
+ // =====================================>
21
+ strCamel(value: string, delimiter: string = ""): string {
22
+ return toWords(value).map((w, i) => i === 0 ? w : w[0].toUpperCase() + w.slice(1)).join(delimiter);
23
+ },
24
+
25
+ // =====================================>
26
+ // ## Conversion: format string to pascal case
27
+ // =====================================>
28
+ strPascal(value: string, delimiter: string = ""): string {
29
+ return toWords(value).map(w => w[0].toUpperCase() + w.slice(1)).join(delimiter);
30
+ },
31
+
32
+ // =====================================>
33
+ // ## Conversion: format string to plural
34
+ // =====================================>
35
+ strPlural(value: string): string {
36
+ const match = value.match(/^(.*?)([A-Za-z]+)$/)
37
+ if (!match) return value
38
+
39
+ const [, prefix, word] = match
40
+
41
+ if (word.endsWith("y") && !/[aeiou]y$/i.test(word)) {
42
+ return prefix + word.slice(0, -1) + "ies"
43
+ }
44
+
45
+ if (!word.endsWith("s")) return prefix + word + "s"
46
+
47
+ return value
48
+ },
49
+
50
+ // =====================================>
51
+ // ## Conversion: format string to singular
52
+ // =====================================>
53
+ strSingular(value: string): string {
54
+ const match = value.match(/^(.*?)([A-Za-z]+)$/)
55
+ if (!match) return value
56
+
57
+ const [, prefix, word] = match
58
+
59
+ if (word.endsWith("ies")) {
60
+ return prefix + word.slice(0, -3) + "y"
61
+ }
62
+
63
+ if (word.endsWith("s") && !word.endsWith("ss")) {
64
+ return prefix + word.slice(0, -1)
65
+ }
66
+
67
+ return value
68
+ },
69
+
70
+ // =====================================>
71
+ // ## Conversion: format number to currency
72
+ // =====================================>
73
+ currency: (value: number, locale = "id-ID", currency = "IDR") => { const val = Math.trunc(value); return new Intl.NumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 0, maximumFractionDigits: 2 }).format(val); },
74
+
75
+ // =====================================>
76
+ // ## Conversion: format date string
77
+ // =====================================>
78
+ date: date,
79
+ };
80
+
81
+
82
+
83
+ function toWords(value: string): string[] {
84
+ return value
85
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
86
+ .replace(/[_\-\s]+/g, " ")
87
+ .trim()
88
+ .toLowerCase()
89
+ .split(" ")
90
+ .filter(Boolean)
65
91
  }
@@ -0,0 +1,74 @@
1
+ export function date(dateStr: string, format: string = "DD MMM YYYY"): string {
2
+ const d = new Date(dateStr);
3
+ if (isNaN(d.getTime())) return "Invalid Date";
4
+
5
+ const options: Intl.DateTimeFormatOptions = {};
6
+ if (format.includes("YYYY") || format.includes("YY")) {
7
+ options.year = format.includes("YYYY") ? "numeric" : "2-digit";
8
+ }
9
+ if (format.includes("MMMM") || format.includes("MMM") || format.includes("MM") || format.includes("M")) {
10
+ options.month = format.includes("MMMM") ? "long" : format.includes("MMM") ? "short" : format.includes("MM") ? "2-digit" : "numeric";
11
+ }
12
+ if (format.includes("DD") || format.includes("D")) {
13
+ options.day = format.includes("DD") ? "2-digit" : "numeric";
14
+ }
15
+ if (format.includes("HH") || format.includes("H") || format.includes("hh") || format.includes("h")) {
16
+ options.hour = (format.includes("HH") || format.includes("hh")) ? "2-digit" : "numeric";
17
+ options.hour12 = format.includes("hh") || format.includes("h");
18
+ }
19
+ if (format.includes("mm") || format.includes("m")) {
20
+ options.minute = format.includes("mm") ? "2-digit" : "numeric";
21
+ }
22
+ if (format.includes("ss") || format.includes("s")) {
23
+ options.second = format.includes("ss") ? "2-digit" : "numeric";
24
+ }
25
+
26
+ const parts = new Intl.DateTimeFormat("id-ID", options).formatToParts(d);
27
+ let result = format;
28
+
29
+ if (format.includes("YYYY")) {
30
+ result = result.replace("YYYY", parts.find(p => p.type === "year")?.value || "");
31
+ } else if (format.includes("YY")) {
32
+ result = result.replace("YY", (parts.find(p => p.type === "year")?.value || "").slice(-2));
33
+ }
34
+
35
+ if (format.includes("MMMM")) {
36
+ result = result.replace("MMMM", parts.find(p => p.type === "month")?.value || "");
37
+ } else if (format.includes("MMM")) {
38
+ result = result.replace("MMM", parts.find(p => p.type === "month")?.value || "");
39
+ } else if (format.includes("MM")) {
40
+ result = result.replace("MM", parts.find(p => p.type === "month")?.value || "");
41
+ } else if (format.includes("M")) {
42
+ result = result.replace("M", parts.find(p => p.type === "month")?.value || "");
43
+ }
44
+
45
+ if (format.includes("DD")) {
46
+ result = result.replace("DD", parts.find(p => p.type === "day")?.value || "");
47
+ } else if (format.includes("D")) {
48
+ result = result.replace("D", parts.find(p => p.type === "day")?.value || "");
49
+ }
50
+
51
+ if (format.includes("HH")) {
52
+ result = result.replace("HH", parts.find(p => p.type === "hour")?.value || "");
53
+ } else if (format.includes("H")) {
54
+ result = result.replace("H", parts.find(p => p.type === "hour")?.value || "");
55
+ } else if (format.includes("hh")) {
56
+ result = result.replace("hh", parts.find(p => p.type === "hour")?.value || "");
57
+ } else if (format.includes("h")) {
58
+ result = result.replace("h", parts.find(p => p.type === "hour")?.value || "");
59
+ }
60
+
61
+ if (format.includes("mm")) {
62
+ result = result.replace("mm", parts.find(p => p.type === "minute")?.value || "");
63
+ } else if (format.includes("m")) {
64
+ result = result.replace("m", parts.find(p => p.type === "minute")?.value || "");
65
+ }
66
+
67
+ if (format.includes("ss")) {
68
+ result = result.replace("ss", parts.find(p => p.type === "second")?.value || "");
69
+ } else if (format.includes("s")) {
70
+ result = result.replace("s", parts.find(p => p.type === "second")?.value || "");
71
+ }
72
+
73
+ return result;
74
+ }
package/src/index.ts CHANGED
@@ -8,9 +8,11 @@ export * from "./route";
8
8
  export * from "./storage";
9
9
  export * from "./validation";
10
10
  export * from "./mail";
11
+ export * from "./notification";
11
12
  export * from "./logger";
12
13
  export * from "./registry";
13
14
  export * from "./commands/cli";
15
+ export { DAMigration } from "./commands/runner/da-migration";
14
16
 
15
17
  declare module "knex" {
16
18
  namespace Knex {
@@ -1,177 +1,218 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { registry } from '@utils/registry';
4
-
5
-
6
-
7
- type LogType = "start" | "info" | "error" | "warning" | "cron" | "queue" | "queueError" | "cronError" | "socket" | "socketError";
8
-
9
- export interface AccessLog {
10
- method : string
11
- path : string
12
- status : number
13
- latency : number
14
- ip ?: string | null
15
- agent ?: string | null
16
- at ?: string
17
- }
18
-
19
- export interface ErrorLog {
20
- service ?: string
21
- key ?: string
22
- feature ?: string
23
- error : string | null
24
- reference ?: string | null
25
- at ?: string
26
- }
27
-
28
-
29
-
30
-
31
- const colors: Record<LogType | "default", string> = {
32
- default : "\x1b[0m", // default
33
- start : "\x1b[32m", // green
34
- info : "\x1b[36m", // cyan
35
- error : "\x1b[31m", // red
36
- warning : "\x1b[33m", // yellow
37
- queue : "\x1b[34m", // blue
38
- queueError : "\x1b[31m", // red
39
- cron : "\x1b[35m", // magenta
40
- cronError : "\x1b[31m", // red
41
- socket : "\x1b[35m", // blue
42
- socketError : "\x1b[31m", // red
43
- };
44
-
45
- const prefixes: Record<LogType, string> = {
46
- start : "START",
47
- info : "INFO",
48
- error : "ERROR",
49
- warning : "WARNING",
50
- cron : "CRON",
51
- queue : "QUEUE",
52
- socket : "SOCKET",
53
- queueError : "QUEUE ERROR",
54
- cronError : "CRON ERROR",
55
- socketError : "SOCKET ERROR",
56
- };
57
-
58
- function log(type: LogType, msg: string) {
59
- const color = colors[type];
60
- const prefix = prefixes[type];
61
- // eslint-disable-next-line no-console
62
- console.log(`${color}[${prefix}]${colors.default}`, msg);
63
- }
64
-
65
- export const logger = {
66
- start : (msg: string) => log("start", msg),
67
- info : (msg: string) => log("info", msg),
68
- warning : (msg: string) => log("warning", msg),
69
- queue : (msg: string) => log("queue", msg),
70
- cron : (msg: string) => log("cron", msg),
71
- socket : (msg: string) => log("socket", msg),
72
-
73
- access : (msg: AccessLog) => logAccess(msg),
74
-
75
- error: (msg: string, payload?: ErrorLog) => {
76
- log("error", msg)
77
- payload && logError({...payload, service: payload.service || 'app'})
78
- },
79
- queueError: (msg: string, payload?: ErrorLog) => {
80
- log("queueError", msg)
81
- payload && logError({...payload, service: payload.service || 'queue'})
82
- },
83
- cronError: (msg: string, payload?: ErrorLog) => {
84
- log("cronError", msg)
85
- payload && logError({...payload, service: payload.service || 'cron'})
86
- },
87
- socketError: (msg: string, payload?: ErrorLog) => {
88
- log("socketError", msg)
89
- payload && logError({...payload, service: payload.service || 'socket'})
90
- },
91
- };
92
-
93
-
94
-
95
-
96
-
97
- type DriverName = "file" | "da"
98
-
99
-
100
- const ACCESS_LOG_DRIVER = process.env.ACCESS_LOG_DRIVER || "file"
101
- const ACCESS_LOG_LOG_DIR = process.env.ACCESS_LOG_DIR || "storage/logs/access"
102
- const ACCESS_LOG_QUEUE = process.env.ACCESS_LOG_QUEUE || "access-log"
103
-
104
-
105
- const ERROR_LOG_DRIVER = process.env.ERROR_LOG_DRIVER || "file"
106
- const ERROR_LOG_LOG_DIR = process.env.ERROR_LOG_DIR || "storage/logs/error"
107
- const ERROR_LOG_QUEUE = process.env.ERROR_LOG_QUEUE_PREFIX || "error-log"
108
-
109
-
110
-
111
- // =====================
112
- // ## Access Log Drivers
113
- // =====================
114
- const filePath = () => {
115
- const d = new Date().toISOString().slice(0, 10)
116
- return path.resolve( ACCESS_LOG_LOG_DIR, `access-${d}.log`)
117
- }
118
-
119
- const handlers: Record<DriverName, (log: AccessLog) => Promise<void>> = {
120
- file: async (log) => {
121
- const dir = path.resolve(ACCESS_LOG_LOG_DIR);
122
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
123
-
124
- fs.appendFile(filePath(), JSON.stringify(log) + "\n", () => {})
125
- },
126
- da: async (log) => {
127
- const queue = registry.get('queue')
128
- if (queue) {
129
- try {
130
- await queue.add(ACCESS_LOG_QUEUE, log)
131
- } catch {}
132
- }
133
- }
134
- }
135
-
136
- const activeDrivers: DriverName[] = (ACCESS_LOG_DRIVER).split(",").map(v => v.trim()).filter((v): v is DriverName => v in handlers)
137
-
138
- function logAccess(payload: AccessLog) {
139
- for (const d of activeDrivers) {
140
- handlers[d](payload)
141
- }
142
- }
143
-
144
-
145
-
146
- // =====================
147
- // ## Error Log Drivers
148
- // =====================
149
- const errorFilePath = () => {
150
- const d = new Date().toISOString().slice(0, 10)
151
- return path.resolve(ERROR_LOG_LOG_DIR, `error-${d}.log`)
152
- }
153
-
154
- const errorHandlers: Record<DriverName, (log: ErrorLog) => Promise<void>> = {
155
- file: async (log) => {
156
- const dir = path.resolve(ERROR_LOG_LOG_DIR);
157
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
158
-
159
- fs.appendFile(errorFilePath(), JSON.stringify(log) + "\n", () => {});
160
- },
161
- da: async (log) => {
162
- const queue = registry.get('queue')
163
- if (queue) {
164
- try {
165
- await queue.add(ERROR_LOG_QUEUE, log)
166
- } catch {}
167
- }
168
- }
169
- }
170
-
171
- const activeErrorDrivers: DriverName[] = ERROR_LOG_DRIVER.split(",").map(v => v.trim()).filter((v): v is DriverName => v in errorHandlers)
172
-
173
- function logError(payload: ErrorLog) {
174
- for (const d of activeErrorDrivers) {
175
- errorHandlers[d](payload)
176
- }
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { registry } from '@utils/registry';
4
+
5
+
6
+
7
+ type LogType = "start" | "info" | "error" | "warning" | "cron" | "queue" | "queueError" | "cronError" | "socket" | "socketError";
8
+
9
+ export interface AccessLog {
10
+ method : string
11
+ path : string
12
+ status : number
13
+ latency : number
14
+ ip ?: string | null
15
+ agent ?: string | null
16
+ at ?: string
17
+ }
18
+
19
+ export interface ErrorLog {
20
+ service ?: string
21
+ key ?: string
22
+ feature ?: string
23
+ error : string | null
24
+ reference ?: string | null
25
+ at ?: string
26
+ }
27
+
28
+
29
+
30
+
31
+ const colors: Record<LogType | "default", string> = {
32
+ default : "\x1b[0m", // default
33
+ start : "\x1b[32m", // green
34
+ info : "\x1b[36m", // cyan
35
+ error : "\x1b[31m", // red
36
+ warning : "\x1b[33m", // yellow
37
+ queue : "\x1b[34m", // blue
38
+ queueError : "\x1b[31m", // red
39
+ cron : "\x1b[35m", // magenta
40
+ cronError : "\x1b[31m", // red
41
+ socket : "\x1b[35m", // blue
42
+ socketError : "\x1b[31m", // red
43
+ };
44
+
45
+ const prefixes: Record<LogType, string> = {
46
+ start : "START",
47
+ info : "INFO",
48
+ error : "ERROR",
49
+ warning : "WARNING",
50
+ cron : "CRON",
51
+ queue : "QUEUE",
52
+ socket : "SOCKET",
53
+ queueError : "QUEUE ERROR",
54
+ cronError : "CRON ERROR",
55
+ socketError : "SOCKET ERROR",
56
+ };
57
+
58
+ function log(type: LogType, msg: string) {
59
+ const color = colors[type];
60
+ const prefix = prefixes[type];
61
+ // eslint-disable-next-line no-console
62
+ console.log(`${color}[${prefix}]${colors.default}`, msg);
63
+ }
64
+
65
+ export const logger = {
66
+ // =====================================>
67
+ // ## Logger: log system startup messages
68
+ // =====================================>
69
+ start : (msg: string) => log("start", msg),
70
+
71
+ // =====================================>
72
+ // ## Logger: log general info messages
73
+ // =====================================>
74
+ info : (msg: string) => log("info", msg),
75
+
76
+ // =====================================>
77
+ // ## Logger: log warning messages
78
+ // =====================================>
79
+ warning : (msg: string) => log("warning", msg),
80
+
81
+ // =====================================>
82
+ // ## Logger: log queue-related messages
83
+ // =====================================>
84
+ queue : (msg: string) => log("queue", msg),
85
+
86
+ // =====================================>
87
+ // ## Logger: log cron-related messages
88
+ // =====================================>
89
+ cron : (msg: string) => log("cron", msg),
90
+
91
+ // =====================================>
92
+ // ## Logger: log socket-related messages
93
+ // =====================================>
94
+ socket : (msg: string) => log("socket", msg),
95
+
96
+ // =====================================>
97
+ // ## Logger: log request access details
98
+ // =====================================>
99
+ access : (msg: AccessLog) => logAccess(msg),
100
+
101
+ // =====================================>
102
+ // ## Logger: log error messages
103
+ // =====================================>
104
+ error: (msg: string, payload?: ErrorLog) => {
105
+ log("error", msg)
106
+ payload && logError({...payload, service: payload.service || 'app'})
107
+ },
108
+
109
+ // =====================================>
110
+ // ## Logger: log queue error messages
111
+ // =====================================>
112
+ queueError: (msg: string, payload?: ErrorLog) => {
113
+ log("queueError", msg)
114
+ payload && logError({...payload, service: payload.service || 'queue'})
115
+ },
116
+
117
+ // =====================================>
118
+ // ## Logger: log cron error messages
119
+ // =====================================>
120
+ cronError: (msg: string, payload?: ErrorLog) => {
121
+ log("cronError", msg)
122
+ payload && logError({...payload, service: payload.service || 'cron'})
123
+ },
124
+
125
+ // =====================================>
126
+ // ## Logger: log socket error messages
127
+ // =====================================>
128
+ socketError: (msg: string, payload?: ErrorLog) => {
129
+ log("socketError", msg)
130
+ payload && logError({...payload, service: payload.service || 'socket'})
131
+ },
132
+ };
133
+
134
+
135
+
136
+
137
+
138
+ type DriverName = "file" | "da"
139
+
140
+
141
+ const ACCESS_LOG_DRIVER = process.env.ACCESS_LOG_DRIVER || "file"
142
+ const ACCESS_LOG_LOG_DIR = process.env.ACCESS_LOG_DIR || "storage/logs/access"
143
+ const ACCESS_LOG_QUEUE = process.env.ACCESS_LOG_QUEUE || "access-log"
144
+
145
+
146
+ const ERROR_LOG_DRIVER = process.env.ERROR_LOG_DRIVER || "file"
147
+ const ERROR_LOG_LOG_DIR = process.env.ERROR_LOG_DIR || "storage/logs/error"
148
+ const ERROR_LOG_QUEUE = process.env.ERROR_LOG_QUEUE_PREFIX || "error-log"
149
+
150
+
151
+
152
+ // =====================
153
+ // ## Access Log Drivers
154
+ // =====================
155
+ const filePath = () => {
156
+ const d = new Date().toISOString().slice(0, 10)
157
+ return path.resolve( ACCESS_LOG_LOG_DIR, `access-${d}.log`)
158
+ }
159
+
160
+ const handlers: Record<DriverName, (log: AccessLog) => Promise<void>> = {
161
+ file: async (log) => {
162
+ const dir = path.resolve(ACCESS_LOG_LOG_DIR);
163
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
164
+
165
+ fs.appendFile(filePath(), JSON.stringify(log) + "\n", () => {})
166
+ },
167
+ da: async (log) => {
168
+ const queue = registry.get('queue')
169
+ if (queue) {
170
+ try {
171
+ await queue.add(ACCESS_LOG_QUEUE, log)
172
+ } catch {}
173
+ }
174
+ }
175
+ }
176
+
177
+ const activeDrivers: DriverName[] = (ACCESS_LOG_DRIVER).split(",").map(v => v.trim()).filter((v): v is DriverName => v in handlers)
178
+
179
+ function logAccess(payload: AccessLog) {
180
+ for (const d of activeDrivers) {
181
+ handlers[d](payload)
182
+ }
183
+ }
184
+
185
+
186
+
187
+ // =====================
188
+ // ## Error Log Drivers
189
+ // =====================
190
+ const errorFilePath = () => {
191
+ const d = new Date().toISOString().slice(0, 10)
192
+ return path.resolve(ERROR_LOG_LOG_DIR, `error-${d}.log`)
193
+ }
194
+
195
+ const errorHandlers: Record<DriverName, (log: ErrorLog) => Promise<void>> = {
196
+ file: async (log) => {
197
+ const dir = path.resolve(ERROR_LOG_LOG_DIR);
198
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
199
+
200
+ fs.appendFile(errorFilePath(), JSON.stringify(log) + "\n", () => {});
201
+ },
202
+ da: async (log) => {
203
+ const queue = registry.get('queue')
204
+ if (queue) {
205
+ try {
206
+ await queue.add(ERROR_LOG_QUEUE, log)
207
+ } catch {}
208
+ }
209
+ }
210
+ }
211
+
212
+ const activeErrorDrivers: DriverName[] = ERROR_LOG_DRIVER.split(",").map(v => v.trim()).filter((v): v is DriverName => v in errorHandlers)
213
+
214
+ function logError(payload: ErrorLog) {
215
+ for (const d of activeErrorDrivers) {
216
+ errorHandlers[d](payload)
217
+ }
177
218
  }