@skalfa/skalfa-api-core 1.0.3 → 1.0.8

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 (284) 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 +18 -27
  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/skalfa-controller.d.ts +3 -0
  68. package/dist/commands/make/{light-controller.js → skalfa-controller.js} +9 -9
  69. package/dist/commands/make/skalfa-controller.js.map +1 -0
  70. package/dist/commands/make/skalfa-model.d.ts +3 -0
  71. package/dist/commands/make/{light-model.js → skalfa-model.js} +11 -11
  72. package/dist/commands/make/skalfa-model.js.map +1 -0
  73. package/dist/commands/runner/barrels.js.map +1 -1
  74. package/dist/commands/runner/blueprint/controller-generation.js +2 -2
  75. package/dist/commands/runner/blueprint/controller-generation.js.map +1 -1
  76. package/dist/commands/runner/blueprint/documentation-generation.js.map +1 -1
  77. package/dist/commands/runner/blueprint/migration-generation.js +3 -3
  78. package/dist/commands/runner/blueprint/migration-generation.js.map +1 -1
  79. package/dist/commands/runner/blueprint/model-generation.js +2 -2
  80. package/dist/commands/runner/blueprint/model-generation.js.map +1 -1
  81. package/dist/commands/runner/blueprint/runner.js +7 -8
  82. package/dist/commands/runner/blueprint/runner.js.map +1 -1
  83. package/dist/commands/runner/blueprint/seeder-generation.js +3 -3
  84. package/dist/commands/runner/blueprint/seeder-generation.js.map +1 -1
  85. package/dist/commands/runner/da-migration.js +1 -2
  86. package/dist/commands/runner/da-migration.js.map +1 -1
  87. package/dist/commands/runner/generate-docs.d.ts +2 -0
  88. package/dist/commands/runner/generate-docs.js +400 -0
  89. package/dist/commands/runner/generate-docs.js.map +1 -0
  90. package/dist/commands/runner/migration.js +1 -1
  91. package/dist/commands/runner/migration.js.map +1 -1
  92. package/dist/commands/runner/seeder.js +1 -1
  93. package/dist/commands/runner/seeder.js.map +1 -1
  94. package/dist/commands/stubs/index.d.ts +4 -4
  95. package/dist/commands/stubs/index.js +4 -4
  96. package/dist/commands/stubs/index.js.map +1 -1
  97. package/dist/context/context.js +6 -0
  98. package/dist/context/context.js.map +1 -1
  99. package/dist/controller/controller.d.ts +17 -30
  100. package/dist/controller/controller.js +39 -121
  101. package/dist/controller/controller.js.map +1 -1
  102. package/dist/controller/response.d.ts +6 -0
  103. package/dist/controller/response.js +63 -0
  104. package/dist/controller/response.js.map +1 -0
  105. package/dist/controller/storage.d.ts +9 -0
  106. package/dist/controller/storage.js +56 -0
  107. package/dist/controller/storage.js.map +1 -0
  108. package/dist/conversion/conversion.d.ts +3 -0
  109. package/dist/conversion/conversion.js +28 -4
  110. package/dist/conversion/conversion.js.map +1 -1
  111. package/dist/conversion/date.d.ts +1 -0
  112. package/dist/conversion/date.js +77 -0
  113. package/dist/conversion/date.js.map +1 -0
  114. package/dist/index.d.ts +2 -0
  115. package/dist/index.js +2 -0
  116. package/dist/index.js.map +1 -1
  117. package/dist/logger/logger.js +33 -0
  118. package/dist/logger/logger.js.map +1 -1
  119. package/dist/mail/mail.js +6 -6
  120. package/dist/mail/mail.js.map +1 -1
  121. package/dist/middleware/access-log.d.ts +31 -0
  122. package/dist/middleware/access-log.js +13 -0
  123. package/dist/middleware/access-log.js.map +1 -0
  124. package/dist/middleware/auth.d.ts +37 -0
  125. package/dist/middleware/auth.js +16 -0
  126. package/dist/middleware/auth.js.map +1 -0
  127. package/dist/middleware/body-parse.d.ts +35 -0
  128. package/dist/middleware/body-parse.js +87 -0
  129. package/dist/middleware/body-parse.js.map +1 -0
  130. package/dist/middleware/context.d.ts +29 -0
  131. package/dist/middleware/context.js +8 -0
  132. package/dist/middleware/context.js.map +1 -0
  133. package/dist/middleware/cors.d.ts +31 -0
  134. package/dist/middleware/cors.js +27 -0
  135. package/dist/middleware/cors.js.map +1 -0
  136. package/dist/middleware/error-handler.d.ts +33 -0
  137. package/dist/middleware/error-handler.js +17 -0
  138. package/dist/middleware/error-handler.js.map +1 -0
  139. package/dist/middleware/middleware.d.ts +31 -10
  140. package/dist/middleware/middleware.js +41 -209
  141. package/dist/middleware/middleware.js.map +1 -1
  142. package/dist/middleware/private.d.ts +29 -0
  143. package/dist/middleware/private.js +8 -0
  144. package/dist/middleware/private.js.map +1 -0
  145. package/dist/middleware/rate-limiter.d.ts +32 -0
  146. package/dist/middleware/rate-limiter.js +30 -0
  147. package/dist/middleware/rate-limiter.js.map +1 -0
  148. package/dist/notification/index.d.ts +1 -0
  149. package/dist/notification/index.js +2 -0
  150. package/dist/notification/index.js.map +1 -0
  151. package/dist/notification/notification.d.ts +16 -0
  152. package/dist/notification/notification.js +64 -0
  153. package/dist/notification/notification.js.map +1 -0
  154. package/dist/permission/permission.js +9 -0
  155. package/dist/permission/permission.js.map +1 -1
  156. package/dist/registry/registry.d.ts +0 -6
  157. package/dist/registry/registry.js +6 -6
  158. package/dist/registry/registry.js.map +1 -1
  159. package/dist/storage/storage.d.ts +3 -3
  160. package/dist/storage/storage.js.map +1 -1
  161. package/dist/validation/validation.js +43 -51
  162. package/dist/validation/validation.js.map +1 -1
  163. package/package.json +4 -4
  164. package/src/auth/auth.ts +21 -252
  165. package/src/auth/create-access-token.ts +29 -0
  166. package/src/auth/create-user-mail-token.ts +24 -0
  167. package/src/auth/helpers/generate-agent-id.ts +8 -0
  168. package/src/auth/helpers/get-request-ip.ts +3 -0
  169. package/src/auth/helpers/get-user-permissions.ts +15 -0
  170. package/src/auth/helpers/index.ts +3 -0
  171. package/src/auth/list-user-sessions.ts +11 -0
  172. package/src/auth/revalidate-user-permissions-by-role.ts +13 -0
  173. package/src/auth/revalidate-user-permissions.ts +26 -0
  174. package/src/auth/revoke-access-token.ts +5 -0
  175. package/src/auth/verify-access-token.ts +56 -0
  176. package/src/auth/verify-user-mail-token.ts +24 -0
  177. package/src/commands/cli.ts +19 -29
  178. package/src/commands/make/basic-controller.ts +4 -2
  179. package/src/commands/make/basic-migration.ts +5 -3
  180. package/src/commands/make/basic-model.ts +3 -1
  181. package/src/commands/make/basic-seeder.ts +3 -1
  182. package/src/commands/make/blueprint.ts +3 -1
  183. package/src/commands/make/da-migration.ts +6 -5
  184. package/src/commands/make/mail.ts +4 -2
  185. package/src/commands/make/notification.ts +3 -1
  186. package/src/commands/make/queue.ts +3 -1
  187. package/src/commands/make/resource.ts +21 -0
  188. package/src/commands/make/{light-controller.ts → skalfa-controller.ts} +10 -8
  189. package/src/commands/make/{light-model.ts → skalfa-model.ts} +12 -10
  190. package/src/commands/runner/barrels.ts +4 -0
  191. package/src/commands/runner/blueprint/controller-generation.ts +4 -2
  192. package/src/commands/runner/blueprint/documentation-generation.ts +2 -0
  193. package/src/commands/runner/blueprint/migration-generation.ts +5 -3
  194. package/src/commands/runner/blueprint/model-generation.ts +4 -2
  195. package/src/commands/runner/blueprint/runner.ts +15 -8
  196. package/src/commands/runner/blueprint/seeder-generation.ts +5 -3
  197. package/src/commands/runner/da-migration.ts +3 -2
  198. package/src/commands/runner/generate-docs.ts +495 -0
  199. package/src/commands/runner/migration.ts +1 -1
  200. package/src/commands/runner/seeder.ts +1 -1
  201. package/src/commands/stubs/index.ts +4 -4
  202. package/src/context/context.ts +23 -17
  203. package/src/controller/controller.ts +124 -239
  204. package/src/controller/response.ts +78 -0
  205. package/src/controller/storage.ts +78 -0
  206. package/src/conversion/conversion.ts +90 -64
  207. package/src/conversion/date.ts +74 -0
  208. package/src/index.ts +2 -0
  209. package/src/logger/logger.ts +217 -176
  210. package/src/mail/mail.ts +85 -85
  211. package/src/middleware/access-log.ts +15 -0
  212. package/src/middleware/auth.ts +19 -0
  213. package/src/middleware/body-parse.ts +83 -0
  214. package/src/middleware/context.ts +11 -0
  215. package/src/middleware/cors.ts +31 -0
  216. package/src/middleware/error-handler.ts +20 -0
  217. package/src/middleware/middleware.ts +91 -288
  218. package/src/middleware/private.ts +8 -0
  219. package/src/middleware/rate-limiter.ts +41 -0
  220. package/src/notification/index.ts +1 -0
  221. package/src/notification/notification.ts +86 -0
  222. package/src/permission/permission.ts +140 -136
  223. package/src/registry/registry.ts +17 -15
  224. package/src/route/route.ts +11 -11
  225. package/src/storage/storage.ts +104 -106
  226. package/src/validation/validation.ts +322 -346
  227. package/dist/auth.util.d.ts +0 -19
  228. package/dist/auth.util.js +0 -183
  229. package/dist/auth.util.js.map +0 -1
  230. package/dist/commands/make/light-controller.d.ts +0 -3
  231. package/dist/commands/make/light-controller.js.map +0 -1
  232. package/dist/commands/make/light-model.d.ts +0 -3
  233. package/dist/commands/make/light-model.js.map +0 -1
  234. package/dist/context.util.d.ts +0 -7
  235. package/dist/context.util.js +0 -11
  236. package/dist/context.util.js.map +0 -1
  237. package/dist/controller.util.d.ts +0 -118
  238. package/dist/controller.util.js +0 -144
  239. package/dist/controller.util.js.map +0 -1
  240. package/dist/conversion.util.d.ts +0 -8
  241. package/dist/conversion.util.js +0 -52
  242. package/dist/conversion.util.js.map +0 -1
  243. package/dist/db/db.d.ts +0 -84
  244. package/dist/db/db.js +0 -177
  245. package/dist/db/db.js.map +0 -1
  246. package/dist/db/index.d.ts +0 -1
  247. package/dist/db/index.js +0 -2
  248. package/dist/db/index.js.map +0 -1
  249. package/dist/db.util.d.ts +0 -84
  250. package/dist/db.util.js +0 -177
  251. package/dist/db.util.js.map +0 -1
  252. package/dist/logger.util.d.ts +0 -30
  253. package/dist/logger.util.js +0 -126
  254. package/dist/logger.util.js.map +0 -1
  255. package/dist/mail.util.d.ts +0 -21
  256. package/dist/mail.util.js +0 -53
  257. package/dist/mail.util.js.map +0 -1
  258. package/dist/middleware.util.d.ts +0 -263
  259. package/dist/middleware.util.js +0 -233
  260. package/dist/middleware.util.js.map +0 -1
  261. package/dist/model/index.d.ts +0 -3
  262. package/dist/model/index.js +0 -4
  263. package/dist/model/index.js.map +0 -1
  264. package/dist/model/model.d.ts +0 -204
  265. package/dist/model/model.js +0 -1495
  266. package/dist/model/model.js.map +0 -1
  267. package/dist/model.util.d.ts +0 -204
  268. package/dist/model.util.js +0 -1495
  269. package/dist/model.util.js.map +0 -1
  270. package/dist/permission.util.d.ts +0 -38
  271. package/dist/permission.util.js +0 -91
  272. package/dist/permission.util.js.map +0 -1
  273. package/dist/registry.util.d.ts +0 -28
  274. package/dist/registry.util.js +0 -19
  275. package/dist/registry.util.js.map +0 -1
  276. package/dist/route.util.d.ts +0 -1
  277. package/dist/route.util.js +0 -12
  278. package/dist/route.util.js.map +0 -1
  279. package/dist/storage.util.d.ts +0 -56
  280. package/dist/storage.util.js +0 -82
  281. package/dist/storage.util.js.map +0 -1
  282. package/dist/validation.util.d.ts +0 -7
  283. package/dist/validation.util.js +0 -237
  284. package/dist/validation.util.js.map +0 -1
@@ -0,0 +1,15 @@
1
+ import { db } from '@skalfa/skalfa-orm'
2
+
3
+ export async function getUserPermissions(userId: number): Promise<string[]> {
4
+ const roleIds = await db("user_roles").where("user_id", userId).pluck("role_id")
5
+
6
+ if (roleIds.length === 0) return []
7
+
8
+ const rows = await db("permissions").whereIn("role_id", roleIds).pluck("permissions")
9
+
10
+ return Array.from(
11
+ new Set(
12
+ rows.flatMap((p: any) => p ?? [])
13
+ )
14
+ )
15
+ }
@@ -0,0 +1,3 @@
1
+ export * from './generate-agent-id'
2
+ export * from './get-request-ip'
3
+ export * from './get-user-permissions'
@@ -0,0 +1,11 @@
1
+ import { db } from '@skalfa/skalfa-orm'
2
+
3
+ export async function listUserSessions(userId: number, currentTokenId?: number) {
4
+ const rows = await db("user_access_tokens").select(["id", "agent", "created_at", "last_used_at", "last_used_ip","expired_at"]).where("user_id", userId).orderBy("last_used_at", "desc")
5
+
6
+ return rows.map((r: any) => ({
7
+ ...r,
8
+ is_active : r.revoked_at === null,
9
+ is_current : r.id === currentTokenId,
10
+ }))
11
+ }
@@ -0,0 +1,13 @@
1
+ import { db } from '@skalfa/skalfa-orm'
2
+ import { registry } from '@utils/registry'
3
+
4
+ export async function revalidateUserPermissionsByRole(roleId: number) {
5
+ const userIds = await db("user_roles").where("role_id", roleId).pluck("user_id")
6
+
7
+ const queue = registry.get('queue')
8
+ if (queue) {
9
+ for (const userId of userIds) {
10
+ await queue.add("auth:revalidate-permission", { userId })
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,26 @@
1
+ import { db } from '@skalfa/skalfa-orm'
2
+ import { registry } from '@utils/registry'
3
+ import { AUTH_CACHE } from './auth'
4
+ import { getUserPermissions } from './helpers'
5
+
6
+ export async function revalidateUserPermissions(userId: number) {
7
+ const permissions = await getUserPermissions(userId)
8
+
9
+ const tokenIds = await db("user_access_tokens").where("user_id", userId).pluck("id")
10
+
11
+ if (tokenIds.length === 0) return
12
+
13
+ await db("user_access_tokens").whereIn("id", tokenIds).update({
14
+ permissions : JSON.stringify(permissions),
15
+ updated_at : new Date(),
16
+ })
17
+
18
+ if (AUTH_CACHE) {
19
+ const redis = registry.get('redis')
20
+ if (redis) {
21
+ await Promise.all(
22
+ tokenIds.map((id: any) => redis.del(`auth:token:${id}`))
23
+ )
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,5 @@
1
+ import { db } from '@skalfa/skalfa-orm'
2
+
3
+ export async function revokeAccessToken(id: number) {
4
+ return db.table('user_access_tokens').where("id", id).delete()
5
+ }
@@ -0,0 +1,56 @@
1
+ import bcrypt from "bcrypt";
2
+ import { db } from '@skalfa/skalfa-orm'
3
+ import { registry } from '@utils/registry'
4
+ import { AUTH_CACHE, AUTH_CACHE_TTL } from './auth'
5
+ import { generateAgentId, getRequestIp } from './helpers'
6
+
7
+ export async function verifyAccessToken(token: string, req?: Request) {
8
+ if (!token.includes("|")) return null
9
+
10
+ const [tokenId, plain] = token.split("|", 2)
11
+ const agent = req ? generateAgentId(req) : ""
12
+ const ip = req ? getRequestIp(req) : ""
13
+
14
+ const cacheKey = `auth:token:${tokenId}`
15
+
16
+ if (AUTH_CACHE) {
17
+ const redis = registry.get('redis')
18
+ if (redis) {
19
+ const cached = await redis.get(cacheKey)
20
+ if (cached) {
21
+ const session = JSON.parse(cached)
22
+ if (session.agent !== agent) return null
23
+ return session
24
+ }
25
+ }
26
+ }
27
+
28
+ const tokenRecord = await db("user_access_tokens").where("id", tokenId).first()
29
+
30
+ if (!tokenRecord) return null
31
+ if (tokenRecord.agent !== agent) return null
32
+
33
+ const valid = await bcrypt.compare(plain, tokenRecord.token)
34
+ if (!valid) return null
35
+
36
+ await db("user_access_tokens").where("id", tokenRecord.id).update({ last_used_at: new Date(), last_used_ip: ip })
37
+
38
+ const user = await db("users").where("id", tokenRecord.user_id).first()
39
+
40
+ if (AUTH_CACHE) {
41
+ const redis = registry.get('redis')
42
+ if (redis) {
43
+ await redis.setex(
44
+ cacheKey,
45
+ AUTH_CACHE_TTL,
46
+ JSON.stringify({
47
+ user : user,
48
+ agent : tokenRecord.agent,
49
+ permissions : tokenRecord.permission,
50
+ })
51
+ )
52
+ }
53
+ }
54
+
55
+ return { user, token: tokenRecord, permissions: tokenRecord.permission }
56
+ }
@@ -0,0 +1,24 @@
1
+ import crypto from 'crypto'
2
+ import { db } from '@skalfa/skalfa-orm'
3
+
4
+ export async function verifyUserMailToken(userId: number, token: string) {
5
+ const hashedToken = crypto.createHash("sha256").update(token).digest("hex");
6
+
7
+ const record = await db.table("user_mail_tokens")
8
+ .where("user_id", userId)
9
+ .whereNull("used_at")
10
+ .orderBy("id", "desc")
11
+ .first();
12
+
13
+ if (!record) return false
14
+
15
+ if (record.token !== hashedToken) return false;
16
+
17
+ const createdAt = new Date(record.created_at);
18
+ const now = new Date();
19
+ const diffMinutes = (now.getTime() - createdAt.getTime()) / (1000 * 60);
20
+
21
+ if (diffMinutes > 10) return false;
22
+
23
+ return true;
24
+ }
@@ -2,22 +2,19 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { Command } from "commander";
4
4
 
5
- // Basic commands (always available)
6
5
  import { makeControllerCommand } from "./make/basic-controller";
7
- import { makeLightControllerCommand } from "./make/light-controller";
6
+ import { makeSkalfaControllerCommand } from "./make/skalfa-controller";
8
7
  import { barrelsCommand, watchBarrelsCommand } from "./runner/barrels";
9
-
10
- // ORM commands (optional)
11
8
  import { makeModelCommand } from "./make/basic-model";
12
9
  import { makeSeederCommand } from "./make/basic-seeder";
13
10
  import { makeMigrationCommand } from "./make/basic-migration";
14
- import { makeLightModelCommand } from "./make/light-model";
11
+ import { makeSkalfaModelCommand } from "./make/skalfa-model";
15
12
  import { makeBlueprintCommand } from "./make/blueprint";
13
+ import { makeResourceCommand } from "./make/resource";
16
14
  import { migrateCommand, migrateFreshCommand } from "./runner/migration";
17
15
  import { seederCommand } from "./runner/seeder";
18
16
  import { blueprintCommand } from "./runner/blueprint/runner";
19
-
20
- // Extension-specific commands
17
+ import { generateDocsCommand } from "./runner/generate-docs";
21
18
  import { makeQueueCommand } from "./make/queue";
22
19
  import { makeMailCommand } from "./make/mail";
23
20
  import { makeNotificationCommand } from "./make/notification";
@@ -25,7 +22,6 @@ import { makeDaMigrationCommand } from "./make/da-migration";
25
22
  import { daMigrateCommand, daMigrateFreshCommand } from "./runner/da-migration";
26
23
 
27
24
  export function runCli() {
28
- // Read package.json to dynamically detect installed extensions
29
25
  let dependencies: Record<string, string> = {};
30
26
  try {
31
27
  const pkgPath = path.join(process.cwd(), "package.json");
@@ -35,50 +31,44 @@ export function runCli() {
35
31
  }
36
32
  } catch {}
37
33
 
38
- const hasOrm = !!dependencies["@skalfa/skalfa-orm"];
39
34
  const hasMail = !!dependencies["@skalfa/mail"] || !!dependencies["skalfa-mail"];
40
35
  const hasNotification = !!dependencies["@skalfa/notification"] || !!dependencies["skalfa-notification"];
41
36
  const hasQueue = !!dependencies["@skalfa/queue"] || !!dependencies["@skalfa/redis"] || !!dependencies["skalfa-queue"] || !!dependencies["skalfa-redis"];
42
37
  const hasDa = !!dependencies["@skalfa/da"] || !!dependencies["skalfa-da"] || !!dependencies["@clickhouse/client"];
43
38
 
44
39
  const program = new Command();
45
- program.name("skalfa").description("Skalfa Local CLI").version("1.0.0");
40
+ program.name("skalfa").description("Skalfa-api CLI").version("1.0.0");
46
41
 
47
- // 1. Add Core / Basic commands
48
- program.addCommand(makeControllerCommand);
49
- program.addCommand(makeLightControllerCommand);
50
42
  program.addCommand(barrelsCommand);
43
+
44
+ program.addCommand(makeControllerCommand);
45
+ program.addCommand(makeSkalfaControllerCommand);
51
46
  program.addCommand(watchBarrelsCommand);
47
+ program.addCommand(makeModelCommand);
48
+ program.addCommand(makeMigrationCommand);
49
+ program.addCommand(makeSeederCommand);
50
+ program.addCommand(makeSkalfaModelCommand);
51
+ program.addCommand(makeBlueprintCommand);
52
+ program.addCommand(makeResourceCommand);
52
53
 
53
- // 2. Add ORM commands if installed
54
- if (hasOrm) {
55
- program.addCommand(makeModelCommand);
56
- program.addCommand(makeMigrationCommand);
57
- program.addCommand(makeSeederCommand);
58
- program.addCommand(makeLightModelCommand);
59
- program.addCommand(makeBlueprintCommand);
60
- program.addCommand(migrateCommand);
61
- program.addCommand(migrateFreshCommand);
62
- program.addCommand(seederCommand);
63
- program.addCommand(blueprintCommand);
64
- }
54
+ program.addCommand(migrateCommand);
55
+ program.addCommand(migrateFreshCommand);
56
+ program.addCommand(seederCommand);
57
+ program.addCommand(blueprintCommand);
58
+ program.addCommand(generateDocsCommand);
65
59
 
66
- // 3. Add Mail commands if installed
67
60
  if (hasMail) {
68
61
  program.addCommand(makeMailCommand);
69
62
  }
70
63
 
71
- // 4. Add Notification commands if installed
72
64
  if (hasNotification) {
73
65
  program.addCommand(makeNotificationCommand);
74
66
  }
75
67
 
76
- // 5. Add Queue commands if installed
77
68
  if (hasQueue) {
78
69
  program.addCommand(makeQueueCommand);
79
70
  }
80
71
 
81
- // 6. Add Data Analytics / OLAP commands if installed
82
72
  if (hasDa) {
83
73
  program.addCommand(makeDaMigrationCommand);
84
74
  program.addCommand(daMigrateCommand);
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { basicControllerStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:controller
9
11
  // =====================================>
@@ -11,7 +13,7 @@ export const makeControllerCommand = new Command("make:controller")
11
13
  .argument("<name>", "Name of controller")
12
14
  .description("Create new controller")
13
15
  .action((controllerName) => {
14
- const basePath = path.join(process.cwd(), "src", "controllers");
16
+ const basePath = path.join(process.cwd(), "app", "controllers");
15
17
 
16
18
  if (!controllerName || controllerName.trim() === "") {
17
19
  logger.error("Controller name invalid!");
@@ -41,7 +43,7 @@ export const makeControllerCommand = new Command("make:controller")
41
43
 
42
44
  let content = basicControllerStub;
43
45
  content = content.replace(/{{\s*name\s*}}/g, name || "");
44
-
46
+
45
47
  writeFileSync(filePath, content);
46
48
 
47
49
  logger.info(`Controller ${controllerName} created!`);
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { basicMigrationStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:migration
9
11
  // =====================================>
@@ -13,8 +15,11 @@ export const makeMigrationCommand = new Command("make:migration")
13
15
  .description("Membuat file migration baru")
14
16
  .action((name, options) => {
15
17
  makeMigration(name, options);
18
+ process.exit(0);
16
19
  });
17
20
 
21
+
22
+
18
23
  // =====================================>
19
24
  // ## Command: migration helpers
20
25
  // =====================================>
@@ -28,7 +33,6 @@ export const makeMigration = (
28
33
 
29
34
  const baseDir = path.join(
30
35
  process.cwd(),
31
- "src",
32
36
  "database",
33
37
  "migrations"
34
38
  );
@@ -66,8 +70,6 @@ export const makeMigration = (
66
70
  writeFileSync(filePath, content);
67
71
 
68
72
  logger.info(`Migration created: ${path.relative(baseDir, filePath)}`);
69
-
70
- process.exit(0);
71
73
  };
72
74
 
73
75
  const migrationPrefixFile = (date: Date) => {
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { basicModelStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:model
9
11
  // =====================================>
@@ -14,7 +16,7 @@ export const makeModelCommand = new Command("make:model")
14
16
  const name = conversion.strPascal(modelName);
15
17
  const filename = conversion.strSlug(modelName) + ".model.ts";
16
18
 
17
- const filePath = path.join(process.cwd(), "src", "models", filename);
19
+ const filePath = path.join(process.cwd(), "app", "models", filename);
18
20
 
19
21
  if (!existsSync(path.dirname(filePath))) {
20
22
  mkdirSync(path.dirname(filePath), { recursive: true });
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { basicSeederStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:seeder
9
11
  // =====================================>
@@ -21,7 +23,7 @@ export const makeSeeder = (seederName: string, model?: string) => {
21
23
  const filename = conversion.strSlug(seederName) + ".seeder.ts";
22
24
  const modelName = model || conversion.strPascal(seederName);
23
25
 
24
- const dir = path.join(process.cwd(), "src", "database", "seeders");
26
+ const dir = path.join(process.cwd(), "database", "seeders");
25
27
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
26
28
 
27
29
  const filePath = path.join(dir, filename);
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { blueprintStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:blueprint
9
11
  // =====================================>
@@ -11,7 +13,7 @@ export const makeBlueprintCommand = new Command("make:blueprint")
11
13
  .argument("<name>", "Name of blueprint")
12
14
  .description("Create new blueprint")
13
15
  .action((name) => {
14
- const basePath = path.join(process.cwd(), "src", "blueprints");
16
+ const basePath = path.join(process.cwd(), "blueprints");
15
17
 
16
18
  if (!name || name.trim() === "") {
17
19
  logger.error("Blueprint name invalid!");
@@ -4,10 +4,12 @@ import { Command } from "commander";
4
4
  import { logger } from "@utils";
5
5
  import { daMigrationStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:da:migration
9
11
  // =====================================>
10
- export const makeDaMigrationCommand = new Command("make:da:migration")
12
+ export const makeDaMigrationCommand = new Command("make:da-migration")
11
13
  .argument("<name>", "Nama migration")
12
14
  .option("--init", "Buat migration init (0000_00)")
13
15
  .description("Membuat file migration baru")
@@ -24,9 +26,8 @@ export const makeDaMigration = (
24
26
 
25
27
  const baseDir = path.join(
26
28
  process.cwd(),
27
- "src",
28
- "database",
29
- "da.migrations"
29
+ "analytic",
30
+ "migrations"
30
31
  );
31
32
 
32
33
  let targetDir: string;
@@ -62,7 +63,7 @@ export const makeDaMigration = (
62
63
  writeFileSync(filePath, content);
63
64
 
64
65
  logger.info(
65
- `DA Migration created: ${path.relative(baseDir, filePath)}`
66
+ `Analytics Migration created: ${path.relative(baseDir, filePath)}`
66
67
  );
67
68
 
68
69
  process.exit(0);
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { mailStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:mail
9
11
  // =====================================>
@@ -11,8 +13,8 @@ export const makeMailCommand = new Command("make:mail")
11
13
  .argument("<name>", "Name of mail")
12
14
  .description("Create new mail")
13
15
  .action((name) => {
14
- const basePath = path.join(process.cwd(), "src", "outputs", "mails");
15
- const templatePath = path.join(process.cwd(), "src", "outputs", "mails", "templates");
16
+ const basePath = path.join(process.cwd(), "app", "outputs", "mails");
17
+ const templatePath = path.join(process.cwd(), "app", "outputs", "mails", "templates");
16
18
 
17
19
  if (!name || name.trim() === "") {
18
20
  logger.error("Mail name invalid!");
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { notificationStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:notification
9
11
  // =====================================>
@@ -11,7 +13,7 @@ export const makeNotificationCommand = new Command("make:notification")
11
13
  .argument("<name>", "Name of notification")
12
14
  .description("Create new notification")
13
15
  .action((name) => {
14
- const basePath = path.join(process.cwd(), "src", "outputs", "notifications");
16
+ const basePath = path.join(process.cwd(), "app", "outputs", "notifications");
15
17
 
16
18
  if (!name || name.trim() === "") {
17
19
  logger.error("Notification name invalid!");
@@ -4,6 +4,8 @@ import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
5
  import { queueStub } from "../stubs";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: make:queue
9
11
  // =====================================>
@@ -11,7 +13,7 @@ export const makeQueueCommand = new Command("make:queue")
11
13
  .argument("<name>", "Name of queue")
12
14
  .description("Create new queue")
13
15
  .action((name) => {
14
- const basePath = path.join(process.cwd(), "src", "jobs", "queues");
16
+ const basePath = path.join(process.cwd(), "app", "jobs", "queues");
15
17
 
16
18
  if (!name || name.trim() === "") {
17
19
  logger.error("Queue name invalid!");
@@ -0,0 +1,21 @@
1
+ import { Command } from "commander";
2
+ import { makeSkalfaModel } from "./skalfa-model";
3
+ import { makeSkalfaController } from "./skalfa-controller";
4
+ import { makeMigration } from "./basic-migration";
5
+ import { makeSeeder } from "./basic-seeder";
6
+
7
+
8
+
9
+ // =====================================>
10
+ // ## Command: make:resource
11
+ // =====================================>
12
+ export const makeResourceCommand = new Command("make:resource")
13
+ .argument("<name>", "Name of resource")
14
+ .description("Create a new model, migration, seeder, and controller for a resource")
15
+ .action((name) => {
16
+ makeSkalfaModel(name);
17
+ makeSkalfaController(name);
18
+ makeMigration("create_" + name, { init: true });
19
+ makeSeeder(name);
20
+ process.exit(0);
21
+ });
@@ -2,22 +2,24 @@ import path from "path";
2
2
  import { writeFileSync, mkdirSync, existsSync } from "fs";
3
3
  import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
- import { lightControllerStub } from "../stubs";
5
+ import { skalfaControllerStub } from "../stubs";
6
+
7
+
6
8
 
7
9
  // =====================================>
8
- // ## Command: make:light-controller
10
+ // ## Command: make:skafa-controller
9
11
  // =====================================>
10
- export const makeLightControllerCommand = new Command("make:light-controller")
12
+ export const makeSkalfaControllerCommand = new Command("make:skalfa-controller")
11
13
  .argument("<name>", "Name of controller")
12
14
  .option("-m, --model <model>", "Attach model to controller")
13
- .description("Make the Light Controller")
15
+ .description("Make the Skalfa Controller")
14
16
  .action((name, options) => {
15
- makeLightController(name, options.model);
17
+ makeSkalfaController(name, options.model);
16
18
  process.exit(0);
17
19
  });
18
20
 
19
- export const makeLightController = (controllerName: string, modelName?: string) => {
20
- const basePath = path.join(process.cwd(), "src", "controllers");
21
+ export const makeSkalfaController = (controllerName: string, modelName?: string) => {
22
+ const basePath = path.join(process.cwd(), "app", "controllers");
21
23
 
22
24
  if (!controllerName || controllerName.trim() === "") {
23
25
  logger.error("Controller name invalid!");
@@ -46,7 +48,7 @@ export const makeLightController = (controllerName: string, modelName?: string)
46
48
  logger.info(`Create folder ${targetDir}...`);
47
49
  }
48
50
 
49
- let stub = lightControllerStub;
51
+ let stub = skalfaControllerStub;
50
52
 
51
53
  stub = stub.replace(
52
54
  /{{\s*name\s*}}|{{\s*model\s*}}|{{\s*validations\s*}}|{{\s*marker\s*}}/g,
@@ -2,23 +2,25 @@ import path from "path";
2
2
  import { writeFileSync, mkdirSync, existsSync } from "fs";
3
3
  import { Command } from "commander";
4
4
  import { conversion, logger } from "@utils";
5
- import { makeLightController } from "./light-controller";
5
+ import { makeSkalfaController } from "./skalfa-controller";
6
6
  import { makeMigration } from "./basic-migration";
7
7
  import { makeSeeder } from "./basic-seeder";
8
- import { lightModelStub } from "../stubs";
8
+ import { skalfaModelStub } from "../stubs";
9
+
10
+
9
11
 
10
12
  // =====================================>
11
- // ## Command: make:light-model
13
+ // ## Command: make:skalfa-model
12
14
  // =====================================>
13
- export const makeLightModelCommand = new Command("make:light-model")
15
+ export const makeSkalfaModelCommand = new Command("make:skalfa-model")
14
16
  .argument("<name>", "Name of model")
15
17
  .option("-r", "Generate all resource (controller, migration, seeder)")
16
- .description("Make the Light Model")
18
+ .description("Make the Skalfa Model")
17
19
  .action((name, options) => {
18
- makeLightModel(name);
20
+ makeSkalfaModel(name);
19
21
 
20
22
  if (options.r) {
21
- makeLightController(name);
23
+ makeSkalfaController(name);
22
24
  makeMigration("create_" + name, { init: true });
23
25
  makeSeeder(name);
24
26
  }
@@ -26,11 +28,11 @@ export const makeLightModelCommand = new Command("make:light-model")
26
28
  process.exit(0);
27
29
  });
28
30
 
29
- export const makeLightModel = (modelName: string) => {
31
+ export const makeSkalfaModel = (modelName: string) => {
30
32
  const name = conversion.strPascal(modelName);
31
33
  const filename = conversion.strSlug(modelName) + ".model.ts";
32
34
 
33
- const basePath = path.join(process.cwd(), "src", "models");
35
+ const basePath = path.join(process.cwd(), "app", "models");
34
36
 
35
37
  if (!existsSync(basePath)) {
36
38
  mkdirSync(basePath, { recursive: true });
@@ -43,7 +45,7 @@ export const makeLightModel = (modelName: string) => {
43
45
  return;
44
46
  }
45
47
 
46
- let stub = lightModelStub;
48
+ let stub = skalfaModelStub;
47
49
 
48
50
  stub = stub
49
51
  .replace(/{{\s*name\s*}}/g, name)
@@ -4,6 +4,8 @@ import { exec, execSync } from "child_process";
4
4
  import { Command } from "commander";
5
5
  import { logger } from "@utils";
6
6
 
7
+
8
+
7
9
  // =====================================>
8
10
  // ## Command: barrels (run once)
9
11
  // =====================================>
@@ -29,6 +31,8 @@ export const barrelsCommand = new Command("barrels")
29
31
  }
30
32
  });
31
33
 
34
+
35
+
32
36
  // =====================================>
33
37
  // ## Command: watch:barrels (file watcher)
34
38
  // =====================================>
@@ -2,7 +2,9 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { conversion } from "@utils";
4
4
  import { resolveBlueprintPath } from "./runner";
5
- import { lightControllerStub, routeStub } from "../../stubs";
5
+ import { skalfaControllerStub, routeStub } from "../../stubs";
6
+
7
+
6
8
 
7
9
  // ================================>
8
10
  // ## Command: Blueprint controller generation
@@ -31,7 +33,7 @@ export async function controllerGeneration(
31
33
  ...generateRelationValidations(relations)
32
34
  };
33
35
 
34
- let stub = lightControllerStub;
36
+ let stub = skalfaControllerStub;
35
37
 
36
38
  stub = stub
37
39
  .replace(/{{\s*marker\s*}}/g, marker)
@@ -5,6 +5,8 @@ import { conversion } from "@utils";
5
5
  const ERD_PATH = path.join(process.cwd(), "storage", "documentation", "entity");
6
6
  const API_PATH = path.join(process.cwd(), "storage", "documentation", "api");
7
7
 
8
+
9
+
8
10
  // =========================================>
9
11
  // ## Command: Blueprint documentation generation
10
12
  // =========================================>