@skalfa/skalfa-api 1.0.1 → 1.0.2

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 (34) hide show
  1. package/.env.example +75 -75
  2. package/.github/workflows/publish.yml +7 -0
  3. package/CONTRIBUTING.md +45 -0
  4. package/LICENSE +21 -0
  5. package/README.md +79 -85
  6. package/app/app.ts +74 -74
  7. package/app/controllers/base.controller.ts +16 -16
  8. package/app/controllers/iam/auth.controller.ts +143 -143
  9. package/app/controllers/iam/user.controller.ts +92 -92
  10. package/app/jobs/crons/index.ts +8 -8
  11. package/app/jobs/crons/worker.cron.ts +8 -8
  12. package/app/jobs/queues/access-log.queue.worker.ts +32 -32
  13. package/app/jobs/queues/activity-log.queue.worker.ts +32 -32
  14. package/app/jobs/queues/auth.queue.worker.ts +9 -9
  15. package/app/jobs/queues/error-log.queue.worker.ts +32 -32
  16. package/app/jobs/queues/notification.queue.worker.ts +11 -11
  17. package/app/jobs/queues/worker.queue.ts +37 -37
  18. package/app/jobs/sockets/worker.socket.ts +2 -2
  19. package/app/models/iam/user.model.ts +17 -17
  20. package/app/outputs/mails/templates/layout.mail.stub +102 -102
  21. package/app/outputs/mails/templates/user-mail-token.mail.stub +28 -28
  22. package/app/outputs/mails/user-mail-token.mail.ts +17 -17
  23. package/app/outputs/notifications/example.notification.ts +10 -0
  24. package/app/outputs/notifications/index.ts +1 -0
  25. package/app/routes/base.routes.ts +25 -25
  26. package/barrels.json +9 -9
  27. package/database/da.migrations/0000_00/activity_logs.ts +27 -27
  28. package/database/da.migrations/0000_00/logs.ts +41 -41
  29. package/database/migrations/0000_00/notifications.ts +28 -0
  30. package/database/migrations/0000_00/storages.ts +22 -22
  31. package/database/migrations/0000_00/users.ts +55 -55
  32. package/database/seeders/user.seeder.ts +23 -23
  33. package/eslint.config.mjs +36 -36
  34. package/package.json +40 -39
package/.env.example CHANGED
@@ -1,76 +1,76 @@
1
- # =========================>
2
- # ## APP
3
- # =========================>
4
- APP_NAME=aluna_api
5
- APP_PORT=4000
6
- APP_CORS_ORIGINS=
7
- APP_CORS_METHODS=
8
- APP_CORS_HEADERS=
9
-
10
-
11
- # =========================>
12
- # ## DATABASE (OLTP)
13
- # =========================>
14
- DB_CONNECTION=pg
15
- DB_HOST=127.0.0.1
16
- DB_PORT=5432
17
- DB_USERNAME=postgres
18
- DB_PASSWORD=password
19
- DB_DATABASE=db_aluna_api
20
-
21
-
22
- # =========================>
23
- # ## DATABASE (OLAP)
24
- # =========================>
25
-
26
-
27
- # =========================>
28
- # ## REDIS
29
- # =========================>
30
-
31
-
32
- # =========================>
33
- # ## CRONJOB
34
- # =========================>
35
-
36
-
37
- # =========================>
38
- # ## SOCKET
39
- # =========================>
40
-
41
-
42
- # =========================>
43
- # ## LOGGER
44
- # =========================>
45
- ACCESS_LOG_DRIVER=
46
- ACCESS_LOG_DIR=
47
- ACCESS_LOG_TABLE=
48
- ACCESS_LOG_QUEUE=
49
- ACCESS_LOG_CONCURRENCY=
50
- ACCESS_LOG_FLUSH=
51
-
52
- ERROR_LOG_DRIVER=
53
- ERROR_LOG_DIR=
54
- ERROR_LOG_TABLE=
55
- ERROR_LOG_QUEUE=
56
- ERROR_LOG_CONCURRENCY=
57
- ERROR_LOG_FLUSH=
58
-
59
- ACTIVITY_LOG_DRIVER=
60
- ACTIVITY_LOG_DB_TABLE=
61
- ACTIVITY_LOG_DA_TABLE=
62
- ACTIVITY_LOG_QUEUE=
63
- ACTIVITY_LOG_CONCURRENCY=
64
-
65
-
66
- # =========================>
67
- # ## MAIL
68
- # =========================>
69
- MAIL_MAILER=smtp
70
- MAIL_HOST=smtp.gmail.com
71
- MAIL_PORT=587
72
- MAIL_USERNAME=
73
- MAIL_PASSWORD=
74
- MAIL_ENCRYPTION=tls
75
- MAIL_FROM_ADDRESS=
1
+ # =========================>
2
+ # ## APP
3
+ # =========================>
4
+ APP_NAME=aluna_api
5
+ APP_PORT=4000
6
+ APP_CORS_ORIGINS=
7
+ APP_CORS_METHODS=
8
+ APP_CORS_HEADERS=
9
+
10
+
11
+ # =========================>
12
+ # ## DATABASE (OLTP)
13
+ # =========================>
14
+ DB_CONNECTION=pg
15
+ DB_HOST=127.0.0.1
16
+ DB_PORT=5432
17
+ DB_USERNAME=postgres
18
+ DB_PASSWORD=password
19
+ DB_DATABASE=db_aluna_api
20
+
21
+
22
+ # =========================>
23
+ # ## DATABASE (OLAP)
24
+ # =========================>
25
+
26
+
27
+ # =========================>
28
+ # ## REDIS
29
+ # =========================>
30
+
31
+
32
+ # =========================>
33
+ # ## CRONJOB
34
+ # =========================>
35
+
36
+
37
+ # =========================>
38
+ # ## SOCKET
39
+ # =========================>
40
+
41
+
42
+ # =========================>
43
+ # ## LOGGER
44
+ # =========================>
45
+ ACCESS_LOG_DRIVER=
46
+ ACCESS_LOG_DIR=
47
+ ACCESS_LOG_TABLE=
48
+ ACCESS_LOG_QUEUE=
49
+ ACCESS_LOG_CONCURRENCY=
50
+ ACCESS_LOG_FLUSH=
51
+
52
+ ERROR_LOG_DRIVER=
53
+ ERROR_LOG_DIR=
54
+ ERROR_LOG_TABLE=
55
+ ERROR_LOG_QUEUE=
56
+ ERROR_LOG_CONCURRENCY=
57
+ ERROR_LOG_FLUSH=
58
+
59
+ ACTIVITY_LOG_DRIVER=
60
+ ACTIVITY_LOG_DB_TABLE=
61
+ ACTIVITY_LOG_DA_TABLE=
62
+ ACTIVITY_LOG_QUEUE=
63
+ ACTIVITY_LOG_CONCURRENCY=
64
+
65
+
66
+ # =========================>
67
+ # ## MAIL
68
+ # =========================>
69
+ MAIL_MAILER=smtp
70
+ MAIL_HOST=smtp.gmail.com
71
+ MAIL_PORT=587
72
+ MAIL_USERNAME=
73
+ MAIL_PASSWORD=
74
+ MAIL_ENCRYPTION=tls
75
+ MAIL_FROM_ADDRESS=
76
76
  MAIL_FROM_NAME=
@@ -19,12 +19,19 @@ jobs:
19
19
  node-version: 20
20
20
  registry-url: https://registry.npmjs.org/
21
21
 
22
+ - name: Setup Bun
23
+ uses: oven-sh/setup-bun@v1
24
+ with:
25
+ bun-version: latest
26
+
22
27
  - name: Publish if version bumped
23
28
  run: |
24
29
  LOCAL_VER=$(node -p "require('./package.json').version")
25
30
  NPM_VER=$(npm view @skalfa/skalfa-api version 2>/dev/null || echo "0.0.0")
26
31
  if [ "$LOCAL_VER" != "$NPM_VER" ]; then
27
32
  echo "Publishing @skalfa/skalfa-api $LOCAL_VER (Registry version: $NPM_VER)"
33
+ bun install
34
+
28
35
  npm publish --access public
29
36
  else
30
37
  echo "@skalfa/skalfa-api is up to date ($LOCAL_VER)"
@@ -0,0 +1,45 @@
1
+ # Contributing to @skalfa/skalfa-api
2
+
3
+ Thank you for your interest in contributing to Skalfa! We welcome contributions from the community to help make Skalfa the premier development framework.
4
+
5
+ ## How to Contribute
6
+
7
+ To contribute to this package, please follow these standard open-source steps:
8
+
9
+ ### 1. Fork the Repository
10
+ Fork the official Skalfa repository on GitHub to your personal account.
11
+
12
+ ### 2. Clone Your Fork
13
+ Clone your personal fork to your local machine:
14
+ ```bash
15
+ git clone https://github.com/your-username/skalfa.git
16
+ cd skalfa
17
+ ```
18
+
19
+ ### 3. Create a Feature Branch
20
+ Create a new branch for your feature or bugfix:
21
+ ```bash
22
+ git checkout -b feature/amazing-new-feature
23
+ ```
24
+ *(Use `bugfix/issue-description` for bugfixes).*
25
+
26
+ ### 4. Implement and Commit Your Changes
27
+ Make your changes in the codebase. Write clean, formatted code and ensure all tests and typechecks pass. Commit your changes using semantic commit messages:
28
+ ```bash
29
+ git commit -m "feat: add amazing new feature"
30
+ ```
31
+ *(Use `fix: description` for bugfixes, and `docs: description` for documentation updates).*
32
+
33
+ ### 5. Push to GitHub
34
+ Push your branch to your personal fork on GitHub:
35
+ ```bash
36
+ git push origin feature/amazing-new-feature
37
+ ```
38
+
39
+ ### 6. Submit a Pull Request (PR)
40
+ Go to the official Skalfa repository on GitHub. You will see a prompt to submit a pull request. Click "New Pull Request", describe your changes in detail, link any related issues, and submit it for review by the maintainers.
41
+
42
+ ## Guidelines
43
+ * **Code Style**: Ensure your code conforms to the project's ESLint rules and formatting guidelines.
44
+ * **Type Safety**: Write strict, type-safe TypeScript. Do not bypass the compiler.
45
+ * **Testing**: Run local tests and verify that the build compiles with 0 errors before submitting a PR.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Skalfa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,85 +1,79 @@
1
- ## About Elysia Light
2
-
3
- Bun & Elysia stater kit for API Service Development with CRUD Generation, API Service Configuration, Etc. with elysia light save your time just for more creative thinking.
4
-
5
- <br>
6
-
7
- ## Version Elysia ^ 1.4
8
-
9
- <p align="center"><a href="https://elysiajs.com/" target="_blank"><img src="https://elysiajs.com/assets/elysia_v.webp" width="70%" alt="Elysia Banner"></a></p>
10
-
11
- <br>
12
- <br>
13
-
14
- ## Magic Command
15
-
16
- ### Make Controller
17
-
18
- ```
19
- bun light make:controller {name}
20
- ```
21
-
22
- ### Make Light Controller
23
-
24
- ```
25
- bun light make:light-controller {name} --model={model[optional]}
26
- ```
27
-
28
- ### Make Model
29
-
30
- ```
31
- bun light make:model {name}
32
- ```
33
-
34
- ### Make Light Model
35
-
36
- ```
37
- bun light make:light-model {name}
38
- ```
39
-
40
- ### Make Migration
41
-
42
- ```
43
- bun light make:migration {name}
44
- ```
45
-
46
- ### Run Migration
47
-
48
- ```
49
- bun light migrate
50
- ```
51
-
52
- ### Run Fresh Migration
53
-
54
- ```
55
- bun light migrate:fresh
56
- ```
57
-
58
- ### Make Seeder
59
-
60
- ```
61
- bun light make:seeder {name}
62
- ```
63
-
64
- ### Run Seeder
65
-
66
- ```
67
- bun light seed
68
- ```
69
-
70
- ### Make Blueprint
71
-
72
- ```
73
- bun light make:blueprint {name}
74
- ```
75
-
76
- ### Run Blueprints
77
-
78
- ```
79
- bun light blueprint {name[optional]}
80
- ```
81
-
82
-
83
- ========================= <br>
84
- Creative by: [SEJE Digital](https://sejedigital.com) <br>
85
- ========================= <br>
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/skalfa-framework/skalfa/main/logo/logo-skalfa-full.png" alt="Skalfa Logo" width="300" />
3
+ </p>
4
+
5
+ # @skalfa/skalfa-api
6
+
7
+ > Premium backend starter template powered by Elysia and Bun, pre-configured with modular utilities.
8
+
9
+ ---
10
+
11
+ ## About this Package
12
+
13
+ This package is part of the **Skalfa Framework**, a premium development ecosystem designed to build high-performance, modular web applications and APIs.
14
+
15
+ ---
16
+
17
+ ## Documentation
18
+
19
+ See the usage documentation at [Documentation](https://skalfa.sejedigital.com).
20
+
21
+ ---
22
+
23
+ ## Installation
24
+
25
+ You can install this package using your preferred package manager:
26
+
27
+ ```bash
28
+ # Using npm
29
+ npm install @skalfa/skalfa-api
30
+
31
+ # Using bun
32
+ bun add @skalfa/skalfa-api
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Development & Production Scripts
38
+
39
+ This backend starter template provides the following CLI execution scripts:
40
+
41
+ ### 💻 Development
42
+ * **`bun run dev`**: Starts the Elysia API server in hot-reload watch mode.
43
+ * **`bun run dev:all`**: Concurrently starts the main API server and any background workers (queues, sockets, crons) in development watch mode.
44
+
45
+ ### 📦 Build & Production
46
+ * **`bun run build`**: Compiles the Elysia backend application into optimized production JavaScript.
47
+ * **`bun run start`**: Starts the production-built Elysia API server.
48
+
49
+ ### ⚙️ Background Workers (Optional Extensions)
50
+ * **`bun start:cron`**: Launches the automated cron scheduler and background task runner worker.
51
+ * **`bun start:queue`**: Launches the Redis-backed queue listener and background job worker.
52
+ * **`bun start:socket`**: Launches the real-time Socket.io server gateway.
53
+
54
+ ---
55
+
56
+ ## Pre-installed Dependencies
57
+
58
+ The following key dependencies are packaged and managed within this project:
59
+
60
+ | Dependency | Scope | Version |
61
+ | :--- | :--- | :--- |
62
+ | `@skalfa/skalfa-api-core` | runtime | `^1.0.2` |
63
+ | `@skalfa/skalfa-orm` | runtime | `^1.0.0` |
64
+ | `bcrypt` | runtime | `^6.0.0` |
65
+ | `dotenv` | runtime | `^17.2.2` |
66
+ | `elysia` | runtime | `^1.2.0` |
67
+ | `knex` | runtime | `^3.1.0` |
68
+ | `pg` | runtime | `^8.16.3` |
69
+ | `nodemailer` | runtime | `^7.0.9` |
70
+ | `tsconfig-paths` | runtime | `^4.2.0` |
71
+ | `validator` | runtime | `^13.15.15` |
72
+ | `commander` | runtime | `^12.1.0` |
73
+ | `eslint` | development | `^10.0.0` |
74
+
75
+ ---
76
+
77
+ ## License
78
+
79
+ This package is licensed under the **MIT License**. For full license text, see the [LICENSE](LICENSE) file.
package/app/app.ts CHANGED
@@ -1,74 +1,74 @@
1
- import os from 'os'
2
- import { Elysia } from 'elysia'
3
- import { controller, db, logger, middleware, storage, registry } from "@utils"
4
- import { routes } from '@routes'
5
-
6
-
7
- // =====================================>
8
- // ## Init: middleware & router app
9
- // =====================================>
10
- export const app = new Elysia()
11
- .use(middleware.AccessLog)
12
- .use(middleware.Cors)
13
- .use(middleware.Auth)
14
- .use(middleware.BodyParse)
15
- .use(controller)
16
- .use(storage)
17
- .use(routes)
18
- .use(middleware.ErrorHandler)
19
-
20
-
21
- // =====================================>
22
- // ## Init: database
23
- // =====================================>
24
- if (process.env.DB_HOST && process.env.DB_PORT && process.env.DB_USERNAME && process.env.DB_PASSWORD && process.env.DB_DATABASE) {
25
- db.schema
26
- logger.start(`Database connected ${process.env.DB_DATABASE}!`)
27
- }
28
-
29
-
30
- // =====================================>
31
- // ## Init: database olap
32
- // =====================================>
33
- // if (process.env.DA_HOST && process.env.DA_PORT && process.env.DA_USERNAME && process.env.DA_PASSWORD && process.env.DA_DATABASE) {
34
- // daClient.ping();
35
- // logger.start(`Database (OLAP) connected ${process.env.DA_DATABASE}!`)
36
- // }
37
-
38
-
39
- // =====================================>
40
- // ## Init: redis
41
- // =====================================>
42
- // if (process.env.REDIS_HOST && process.env.REDIS_PORT) {
43
- // redis.on("connect", () => {
44
- // logger.start(`Redis connected ${process.env.REDIS_HOST}:${process.env.REDIS_PORT}!`)
45
- // })
46
- //
47
- // redis.on("error", (err) => {
48
- // const em = err instanceof Error ? err.message : String(err)
49
- // logger.error(`Redis error: ${em}`, { error: em })
50
- // })
51
- // }
52
-
53
-
54
-
55
-
56
-
57
- // =====================================>
58
- // ## Init: running server
59
- // =====================================>
60
- function getLocalIP() {
61
- const interfaces = os.networkInterfaces()
62
- for (const name of Object.keys(interfaces)) {
63
- for (const net of interfaces[name] || []) {
64
- if (net.family === 'IPv4' && !net.internal) return net.address
65
- }
66
- }
67
- }
68
-
69
- app.listen({ port: process.env.APP_PORT, hostname: '0.0.0.0' })
70
- setTimeout(() => logger.start(`Server is running at \n [LOCAL] http://localhost:${process.env.APP_PORT || 4000} \n [NETWORK] http://${getLocalIP()}:${process.env.APP_PORT || 4000}!`), 200)
71
-
72
-
73
-
74
-
1
+ import os from 'os'
2
+ import { Elysia } from 'elysia'
3
+ import { controller, db, logger, middleware, storage, registry } from "@utils"
4
+ import { routes } from '@routes'
5
+
6
+
7
+ // =====================================>
8
+ // ## Init: middleware & router app
9
+ // =====================================>
10
+ export const app = new Elysia()
11
+ .use(middleware.AccessLog)
12
+ .use(middleware.Cors)
13
+ .use(middleware.Auth)
14
+ .use(middleware.BodyParse)
15
+ .use(controller)
16
+ .use(storage)
17
+ .use(routes)
18
+ .use(middleware.ErrorHandler)
19
+
20
+
21
+ // =====================================>
22
+ // ## Init: database
23
+ // =====================================>
24
+ if (process.env.DB_HOST && process.env.DB_PORT && process.env.DB_USERNAME && process.env.DB_PASSWORD && process.env.DB_DATABASE) {
25
+ db.schema
26
+ logger.start(`Database connected ${process.env.DB_DATABASE}!`)
27
+ }
28
+
29
+
30
+ // =====================================>
31
+ // ## Init: database olap
32
+ // =====================================>
33
+ // if (process.env.DA_HOST && process.env.DA_PORT && process.env.DA_USERNAME && process.env.DA_PASSWORD && process.env.DA_DATABASE) {
34
+ // daClient.ping();
35
+ // logger.start(`Database (OLAP) connected ${process.env.DA_DATABASE}!`)
36
+ // }
37
+
38
+
39
+ // =====================================>
40
+ // ## Init: redis
41
+ // =====================================>
42
+ // if (process.env.REDIS_HOST && process.env.REDIS_PORT) {
43
+ // redis.on("connect", () => {
44
+ // logger.start(`Redis connected ${process.env.REDIS_HOST}:${process.env.REDIS_PORT}!`)
45
+ // })
46
+ //
47
+ // redis.on("error", (err) => {
48
+ // const em = err instanceof Error ? err.message : String(err)
49
+ // logger.error(`Redis error: ${em}`, { error: em })
50
+ // })
51
+ // }
52
+
53
+
54
+
55
+
56
+
57
+ // =====================================>
58
+ // ## Init: running server
59
+ // =====================================>
60
+ function getLocalIP() {
61
+ const interfaces = os.networkInterfaces()
62
+ for (const name of Object.keys(interfaces)) {
63
+ for (const net of interfaces[name] || []) {
64
+ if (net.family === 'IPv4' && !net.internal) return net.address
65
+ }
66
+ }
67
+ }
68
+
69
+ app.listen({ port: process.env.APP_PORT, hostname: '0.0.0.0' })
70
+ setTimeout(() => logger.start(`Server is running at \n [LOCAL] http://localhost:${process.env.APP_PORT || 4000} \n [NETWORK] http://${getLocalIP()}:${process.env.APP_PORT || 4000}!`), 200)
71
+
72
+
73
+
74
+
@@ -1,17 +1,17 @@
1
- import { permission } from "@utils";
2
-
3
- export class BaseController {
4
- static async index() {
5
- return {
6
- message: `Welcome to the API of ${process.env.APP_NAME}!`,
7
- };
8
- }
9
-
10
- static async feature() {
11
- return permission.getFeatures()
12
- }
13
-
14
- static async access() {
15
- return permission.getAccesses()
16
- }
1
+ import { permission } from "@utils";
2
+
3
+ export class BaseController {
4
+ static async index() {
5
+ return {
6
+ message: `Welcome to the API of ${process.env.APP_NAME}!`,
7
+ };
8
+ }
9
+
10
+ static async feature() {
11
+ return permission.getFeatures()
12
+ }
13
+
14
+ static async access() {
15
+ return permission.getAccesses()
16
+ }
17
17
  }