@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
@@ -1,136 +1,140 @@
1
- import { ControllerContext } from "elysia"
2
-
3
- type KeyDigit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
4
- export type KeyFeature = `${"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"}${KeyDigit}${KeyDigit}`
5
- export type KeyAccess = `${KeyDigit}${KeyDigit}`
6
- export type KeyPermission = `${KeyFeature}.${KeyAccess}` | KeyAccess
7
-
8
- const features = new Map<KeyFeature, { key: KeyFeature; name: string }>()
9
- const accesses = new Map<KeyAccess, any>()
10
-
11
- type FeatureAccess = Partial<Record<KeyFeature, {
12
- name: string
13
- accesses: Partial<Record<KeyAccess, string>>
14
- }>>
15
-
16
- export const permission = {
17
- register: (def: FeatureAccess) => {
18
- const featureAccessMap = new Map<string, string>()
19
- let defaultFeature: KeyFeature | null = null
20
-
21
- for (const [featureKey, feature] of Object.entries(def)) {
22
- if (!defaultFeature) defaultFeature = featureKey as KeyFeature
23
-
24
- registerFeature({
25
- key: featureKey as KeyFeature,
26
- name: feature.name
27
- })
28
-
29
- for (const [accessKey, accessName] of Object.entries(feature.accesses)) {
30
- const permKey =
31
- `${featureKey}.${String(accessKey).padStart(2, "0")}`
32
-
33
- registerAccess({
34
- featureKey,
35
- accessKey,
36
- accessName,
37
- permKey
38
- })
39
-
40
- featureAccessMap.set(
41
- `${featureKey}.${accessKey}`,
42
- permKey
43
- )
44
- }
45
- }
46
-
47
- return createScopeApi(defaultFeature!)
48
- },
49
-
50
- getFeatures: () => [...features.values()],
51
-
52
- getAccesses: () => {
53
- const result: Record<string, {
54
- key: string
55
- name: string
56
- accesses: { key: string; name: string }[]
57
- }> = {}
58
-
59
- for (const feature of features.values()) {
60
- result[String(feature.key)] = {
61
- key: String(feature.key),
62
- name: feature.name,
63
- accesses: []
64
- }
65
- }
66
-
67
- for (const access of accesses.values()) {
68
- const featureKey = String(access.featureKey)
69
-
70
- if (!result[featureKey]) continue
71
-
72
- result[featureKey].accesses.push({
73
- key: String(access.accessKey).padStart(2, "0"),
74
- name: access.accessName
75
- })
76
- }
77
-
78
- return Object.values(result)
79
- },
80
- }
81
-
82
-
83
- function normalize(
84
- raw: KeyPermission,
85
- defaultFeature?: KeyFeature
86
- ): KeyPermission {
87
- if (!raw.includes(".") && defaultFeature) {
88
- return `${defaultFeature}.${String(raw).padStart(2, "0") as KeyAccess}`
89
- }
90
-
91
- return raw
92
- }
93
-
94
- function registerFeature(f: { key: KeyFeature; name: string }) {
95
- if (!features.has(f.key)) {
96
- features.set(f.key, f)
97
- }
98
- }
99
-
100
- function registerAccess(a: any) {
101
- if (!accesses.has(a.permKey)) {
102
- accesses.set(a.permKey, a)
103
- }
104
- }
105
-
106
- function createPermission(keys: KeyPermission[]) {
107
- return {
108
- keys,
109
-
110
- orHave(raw: KeyPermission) {
111
- return createPermission([
112
- ...this.keys,
113
- normalize(raw) as KeyPermission
114
- ])
115
- },
116
-
117
- guard(c: ControllerContext) {
118
- const permissions = new Set(c.permissions || [])
119
-
120
- const ok = this.keys.some(k => permissions?.has(k))
121
- if (!ok) {
122
- c.responseForbidden()
123
- }
124
- }
125
- }
126
- }
127
-
128
- export function createScopeApi(defaultFeature: KeyFeature) {
129
- return {
130
- have(raw: KeyPermission) {
131
- const key = normalize(raw, defaultFeature)
132
- return createPermission([key])
133
- }
134
- }
135
- }
136
-
1
+ import { ControllerContext } from "elysia"
2
+
3
+ type KeyDigit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
4
+ export type KeyFeature = `${"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"}${KeyDigit}${KeyDigit}`
5
+ export type KeyAccess = `${KeyDigit}${KeyDigit}`
6
+ export type KeyPermission = `${KeyFeature}.${KeyAccess}` | KeyAccess
7
+
8
+ const features = new Map<KeyFeature, { key: KeyFeature; name: string }>()
9
+ const accesses = new Map<KeyAccess, any>()
10
+
11
+ type FeatureAccess = Partial<Record<KeyFeature, {
12
+ name: string
13
+ accesses: Partial<Record<KeyAccess, string>>
14
+ }>>
15
+
16
+ export const permission = {
17
+ // =====================================>
18
+ // ## Permission: register features and accesses
19
+ // =====================================>
20
+ register: (def: FeatureAccess) => {
21
+ const featureAccessMap = new Map<string, string>()
22
+ let defaultFeature: KeyFeature | null = null
23
+
24
+ for (const [featureKey, feature] of Object.entries(def)) {
25
+ if (!defaultFeature) defaultFeature = featureKey as KeyFeature
26
+
27
+ registerFeature({
28
+ key: featureKey as KeyFeature,
29
+ name: feature.name
30
+ })
31
+
32
+ for (const [accessKey, accessName] of Object.entries(feature.accesses)) {
33
+ const permKey =
34
+ `${featureKey}.${String(accessKey).padStart(2, "0")}`
35
+
36
+ registerAccess({
37
+ featureKey,
38
+ accessKey,
39
+ accessName,
40
+ permKey
41
+ })
42
+
43
+ featureAccessMap.set(
44
+ `${featureKey}.${accessKey}`,
45
+ permKey
46
+ )
47
+ }
48
+ }
49
+
50
+ return createScopeApi(defaultFeature!)
51
+ },
52
+
53
+ // =====================================>
54
+ // ## Permission: get registered features list
55
+ // =====================================>
56
+ getFeatures: () => [...features.values()],
57
+
58
+ // =====================================>
59
+ // ## Permission: get registered accesses list
60
+ // =====================================>
61
+ getAccesses: () => {
62
+ const result: Record<string, {
63
+ key: string
64
+ name: string
65
+ accesses: { key: string; name: string }[]
66
+ }> = {}
67
+
68
+ for (const feature of features.values()) {
69
+ result[String(feature.key)] = {
70
+ key: String(feature.key),
71
+ name: feature.name,
72
+ accesses: []
73
+ }
74
+ }
75
+
76
+ for (const access of accesses.values()) {
77
+ const featureKey = String(access.featureKey)
78
+
79
+ if (!result[featureKey]) continue
80
+
81
+ result[featureKey].accesses.push({
82
+ key: String(access.accessKey).padStart(2, "0"),
83
+ name: access.accessName
84
+ })
85
+ }
86
+
87
+ return Object.values(result)
88
+ },
89
+ }
90
+
91
+ function normalize(raw: KeyPermission, defaultFeature?: KeyFeature): KeyPermission {
92
+ if (!raw.includes(".") && defaultFeature) {
93
+ return `${defaultFeature}.${String(raw).padStart(2, "0") as KeyAccess}`
94
+ }
95
+
96
+ return raw
97
+ }
98
+
99
+ function registerFeature(f: { key: KeyFeature; name: string }) {
100
+ if (!features.has(f.key)) {
101
+ features.set(f.key, f)
102
+ }
103
+ }
104
+
105
+ function registerAccess(a: any) {
106
+ if (!accesses.has(a.permKey)) {
107
+ accesses.set(a.permKey, a)
108
+ }
109
+ }
110
+
111
+ function createPermission(keys: KeyPermission[]) {
112
+ return {
113
+ keys,
114
+
115
+ orHave(raw: KeyPermission) {
116
+ return createPermission([
117
+ ...this.keys,
118
+ normalize(raw) as KeyPermission
119
+ ])
120
+ },
121
+
122
+ guard(c: ControllerContext) {
123
+ const permissions = new Set(c.permissions || [])
124
+
125
+ const ok = this.keys.some(k => permissions?.has(k))
126
+ if (!ok) {
127
+ c.responseForbidden()
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ export function createScopeApi(defaultFeature: KeyFeature) {
134
+ return {
135
+ have(raw: KeyPermission) {
136
+ const key = normalize(raw, defaultFeature)
137
+ return createPermission([key])
138
+ }
139
+ }
140
+ }
@@ -1,34 +1,36 @@
1
1
  export interface RedisService {
2
- get(key: string): Promise<string | null>;
3
- setex(key: string, ttl: number, value: string): Promise<any>;
4
- del(key: string | string[]): Promise<any>;
5
- [key: string]: any;
2
+ get(key: string) : Promise<string | null>;
3
+ setex(key: string, ttl: number, value: string) : Promise<any>;
4
+ del(key: string | string[]) : Promise<any>;
5
+ [key: string] : any;
6
6
  }
7
7
 
8
8
  export interface QueueService {
9
- add(name: string, data: any, options?: any): Promise<any>;
10
- [key: string]: any;
9
+ add(name: string, data: any, options?: any) : Promise<any>;
10
+ [key: string] : any;
11
11
  }
12
12
 
13
13
  export interface Registry {
14
- redis?: RedisService;
15
- queue?: QueueService;
16
- [key: string]: any;
14
+ redis ?: RedisService;
15
+ queue ?: QueueService;
16
+ [key: string] : any;
17
17
  }
18
18
 
19
+
20
+
19
21
  class ServiceRegistry {
20
22
  private services: Registry = {};
21
23
 
22
- /**
23
- * Register an optional service instance.
24
- */
24
+ // =====================================>
25
+ // ## Registry: register a service
26
+ // =====================================>
25
27
  register<K extends keyof Registry>(name: K, service: Registry[K]): void {
26
28
  this.services[name] = service;
27
29
  }
28
30
 
29
- /**
30
- * Retrieve a registered service instance.
31
- */
31
+ // =====================================>
32
+ // ## Registry: get a registered service
33
+ // =====================================>
32
34
  get<K extends keyof Registry>(name: K): Registry[K] {
33
35
  return this.services[name];
34
36
  }
@@ -1,12 +1,12 @@
1
- // ================================>
2
- // ## Route: Basic api routers
3
- // ================================>
4
- export function api(app: any, basePath: string, controller: any) {
5
- return app.group(basePath, (group: any) => group
6
- .get("/", controller.index)
7
- .post("/", controller.store)
8
- .get("/:id", controller.show)
9
- .put("/:id", controller.update)
10
- .delete("/:id", controller.destroy)
11
- )
1
+ // ================================>
2
+ // ## Route: Basic api routers
3
+ // ================================>
4
+ export function api(app: any, basePath: string, controller: any) {
5
+ return app.group(basePath, (group: any) => group
6
+ .get("/", controller.index)
7
+ .post("/", controller.store)
8
+ .get("/:id", controller.show)
9
+ .put("/:id", controller.update)
10
+ .delete("/:id", controller.destroy)
11
+ )
12
12
  }
@@ -1,107 +1,105 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { Elysia } from "elysia";
4
- import { db } from "@skalfa/skalfa-orm";
5
-
6
-
7
-
8
- // ================================>
9
- // ## Storage: Middleware storage handler
10
- // ================================>
11
- export const storage = (app: Elysia) => app.get("/storage/*", async ({ params, set, user }: Record<string, any>) => {
12
- const requestedPath = params["*"];
13
- const baseDir = path.resolve("storage", "public");
14
- const targetPath = path.resolve(baseDir, requestedPath);
15
-
16
- if (!targetPath.startsWith(baseDir)) {
17
- set.status = 400;
18
- return { error: "Invalid path" };
19
- }
20
-
21
- if (fs.existsSync(targetPath)) {
22
- const ext = path.extname(targetPath).toLowerCase();
23
- const mimeTypes: Record<string, string> = {
24
- ".jpg" : "image/jpeg",
25
- ".jpeg" : "image/jpeg",
26
- ".png" : "image/png",
27
- ".webp" : "image/webp",
28
- ".gif" : "image/gif",
29
- ".pdf" : "application/pdf",
30
- ".txt" : "text/plain",
31
- ".json" : "application/json",
32
- ".svg" : "image/svg+xml",
33
- };
34
-
35
- const buffer = fs.readFileSync(targetPath);
36
-
37
- set.headers["Content-Type"] = mimeTypes[ext] || "application/octet-stream";
38
- set.headers["Content-Length"] = buffer.length.toString();
39
-
40
- return new Response(buffer);
41
- } else {
42
- const baseDir = path.resolve("storage", "private");
43
- const targetPath = path.resolve(baseDir, requestedPath);
44
-
45
- if (fs.existsSync(targetPath)) {
46
- if (!user) {
47
- set.status = 404
48
- return { error: "File not found" };
49
- }
50
-
51
- if (!db) {
52
- set.status = 404;
53
- return { error: "File not found" };
54
- }
55
-
56
- const file = await db("storages").where({ path: requestedPath, disk: "private" }).first()
57
-
58
- if (!file) {
59
- set.status = 404
60
- return { error: "File not found" }
61
- }
62
-
63
- let hasAccess = file.user_id === user.id
64
-
65
- if (!hasAccess) {
66
- hasAccess = await db("storage_permissions").where("storage_id", file.id)
67
- .andWhere((q: any) => {
68
- q.where("user_id", user.id)
69
- .orWhere("role_id", user.role_id)
70
- })
71
- .first().then(Boolean)
72
- }
73
-
74
-
75
- if (!hasAccess) {
76
- set.status = 404
77
- return { error: "File not found" }
78
- }
79
-
80
- } else {
81
- set.status = 404;
82
- return { error: "File not found" };
83
- }
84
-
85
- const ext = path.extname(targetPath).toLowerCase();
86
- const mimeTypes: Record<string, string> = {
87
- ".jpg" : "image/jpeg",
88
- ".jpeg" : "image/jpeg",
89
- ".png" : "image/png",
90
- ".webp" : "image/webp",
91
- ".gif" : "image/gif",
92
- ".pdf" : "application/pdf",
93
- ".txt" : "text/plain",
94
- ".json" : "application/json",
95
- ".svg" : "image/svg+xml",
96
- };
97
-
98
- const buffer = fs.readFileSync(targetPath);
99
-
100
- set.headers["Content-Type"] = mimeTypes[ext] || "application/octet-stream";
101
- set.headers["Content-Length"] = buffer.length.toString();
102
-
103
- return new Response(buffer);
104
- }
105
-
106
-
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { Elysia } from "elysia";
4
+ import { db } from "@skalfa/skalfa-orm";
5
+
6
+
7
+
8
+ // ================================>
9
+ // ## Storage: Middleware storage handler
10
+ // ================================>
11
+ export const storage = (app: Elysia) => app.get("/storage/*", async ({ params, set, user }: Record<string, any>) => {
12
+ const requestedPath = params["*"];
13
+ const baseDir = path.resolve("storage", "public");
14
+ const targetPath = path.resolve(baseDir, requestedPath);
15
+
16
+ if (!targetPath.startsWith(baseDir)) {
17
+ set.status = 400;
18
+ return { error: "Invalid path" };
19
+ }
20
+
21
+ if (fs.existsSync(targetPath)) {
22
+ const ext = path.extname(targetPath).toLowerCase();
23
+ const mimeTypes: Record<string, string> = {
24
+ ".jpg" : "image/jpeg",
25
+ ".jpeg" : "image/jpeg",
26
+ ".png" : "image/png",
27
+ ".webp" : "image/webp",
28
+ ".gif" : "image/gif",
29
+ ".pdf" : "application/pdf",
30
+ ".txt" : "text/plain",
31
+ ".json" : "application/json",
32
+ ".svg" : "image/svg+xml",
33
+ };
34
+
35
+ const buffer = fs.readFileSync(targetPath);
36
+
37
+ set.headers["Content-Type"] = mimeTypes[ext] || "application/octet-stream";
38
+ set.headers["Content-Length"] = buffer.length.toString();
39
+
40
+ return new Response(buffer);
41
+ } else {
42
+ const baseDir = path.resolve("storage", "private");
43
+ const targetPath = path.resolve(baseDir, requestedPath);
44
+
45
+ if (fs.existsSync(targetPath)) {
46
+ if (!user) {
47
+ set.status = 404
48
+ return { error: "File not found" };
49
+ }
50
+
51
+ if (!db) {
52
+ set.status = 404;
53
+ return { error: "File not found" };
54
+ }
55
+
56
+ const file = await db("storages").where({ path: requestedPath, disk: "private" }).first()
57
+
58
+ if (!file) {
59
+ set.status = 404
60
+ return { error: "File not found" }
61
+ }
62
+
63
+ let hasAccess = file.user_id === user.id
64
+
65
+ if (!hasAccess) {
66
+ hasAccess = await db("storage_permissions").where("storage_id", file.id)
67
+ .andWhere((q: any) => {
68
+ q.where("user_id", user.id)
69
+ .orWhere("role_id", user.role_id)
70
+ })
71
+ .first().then(Boolean)
72
+ }
73
+
74
+
75
+ if (!hasAccess) {
76
+ set.status = 404
77
+ return { error: "File not found" }
78
+ }
79
+
80
+ } else {
81
+ set.status = 404;
82
+ return { error: "File not found" };
83
+ }
84
+
85
+ const ext = path.extname(targetPath).toLowerCase();
86
+ const mimeTypes: Record<string, string> = {
87
+ ".jpg" : "image/jpeg",
88
+ ".jpeg" : "image/jpeg",
89
+ ".png" : "image/png",
90
+ ".webp" : "image/webp",
91
+ ".gif" : "image/gif",
92
+ ".pdf" : "application/pdf",
93
+ ".txt" : "text/plain",
94
+ ".json" : "application/json",
95
+ ".svg" : "image/svg+xml",
96
+ };
97
+
98
+ const buffer = fs.readFileSync(targetPath);
99
+
100
+ set.headers["Content-Type"] = mimeTypes[ext] || "application/octet-stream";
101
+ set.headers["Content-Length"] = buffer.length.toString();
102
+
103
+ return new Response(buffer);
104
+ }
107
105
  });