jcc-express-mvc 1.9.2 → 1.9.4

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 (190) hide show
  1. package/final-documentation/Architecture Concept/Request-Lifecycle.md +137 -0
  2. package/final-documentation/Architecture Concept/Service-Container.md +134 -0
  3. package/final-documentation/Architecture Concept/Service-Provider.md +105 -0
  4. package/final-documentation/Database/Database-Introduction.md +240 -0
  5. package/final-documentation/Database/Migrations.md +319 -0
  6. package/final-documentation/Database/Mongoose.md +125 -0
  7. package/final-documentation/Database/Query-Builder.md +181 -0
  8. package/final-documentation/Database/Seeding.md +93 -0
  9. package/final-documentation/Database/Sequelize.md +147 -0
  10. package/final-documentation/Database/Transactions.md +81 -0
  11. package/final-documentation/Digging Deeper/Broadcasting.md +145 -0
  12. package/final-documentation/Digging Deeper/Cache.md +154 -0
  13. package/final-documentation/Digging Deeper/Carbon.md +220 -0
  14. package/final-documentation/Digging Deeper/Deferred-Functions.md +139 -0
  15. package/final-documentation/Digging Deeper/Events.md +123 -0
  16. package/final-documentation/Digging Deeper/File-Storage.md +160 -0
  17. package/final-documentation/Digging Deeper/HTTP-Client.md +112 -0
  18. package/final-documentation/Digging Deeper/Helpers.md +111 -0
  19. package/final-documentation/Digging Deeper/Logging.md +199 -0
  20. package/final-documentation/Digging Deeper/Mail.md +118 -0
  21. package/final-documentation/Digging Deeper/Monitor.md +871 -0
  22. package/final-documentation/Digging Deeper/Queues.md +175 -0
  23. package/final-documentation/Digging Deeper/Rate-Limiting.md +83 -0
  24. package/final-documentation/Digging Deeper/Strings.md +115 -0
  25. package/final-documentation/Digging Deeper/Task-Scheduling.md +411 -0
  26. package/final-documentation/Getting-Started/Configuration.md +104 -0
  27. package/final-documentation/Getting-Started/Deployment.md +191 -0
  28. package/final-documentation/Getting-Started/Directory-structure.md +121 -0
  29. package/final-documentation/Getting-Started/Frontend.md +183 -0
  30. package/final-documentation/Getting-Started/Installation.md +309 -0
  31. package/final-documentation/Getting-Started/Introduction.md +27 -0
  32. package/final-documentation/JCC-Eloquent/Defining-Model.md +297 -0
  33. package/final-documentation/JCC-Eloquent/JCC-Eloquent-Introduction.md +134 -0
  34. package/final-documentation/JCC-Eloquent/Mutators.md +95 -0
  35. package/final-documentation/JCC-Eloquent/Observer.md +10 -0
  36. package/final-documentation/JCC-Eloquent/Pagination.md +137 -0
  37. package/final-documentation/JCC-Eloquent/Query-Builder.md +346 -0
  38. package/final-documentation/JCC-Eloquent/Relationships.md +113 -0
  39. package/final-documentation/JCC-Eloquent/Retrieving-Models.md +146 -0
  40. package/final-documentation/JCC-Eloquent/Scopes.md +88 -0
  41. package/final-documentation/JCC-Eloquent/SoftDelete.md +92 -0
  42. package/final-documentation/Packages/Cloudinary.md +85 -0
  43. package/final-documentation/Packages/JWT.md +91 -0
  44. package/final-documentation/Packages/Socialite.md +153 -0
  45. package/final-documentation/Security/Authentication.md +132 -0
  46. package/final-documentation/Security/Authorization.md +117 -0
  47. package/final-documentation/Security/Email-Verification.md +80 -0
  48. package/final-documentation/Security/Encryption.md +105 -0
  49. package/final-documentation/Security/Hashing.md +84 -0
  50. package/final-documentation/Testing/Database-Testing.md +109 -0
  51. package/final-documentation/Testing/Feature-Testing.md +249 -0
  52. package/final-documentation/Testing/Introduction.md +101 -0
  53. package/final-documentation/Testing/Testing-Overview.md +63 -0
  54. package/final-documentation/Testing/Unit-Testing.md +118 -0
  55. package/final-documentation/The Basics/Artisan-Node.md +123 -0
  56. package/final-documentation/The Basics/Asset-bundling.md +113 -0
  57. package/final-documentation/The Basics/CSRF-protection.md +142 -0
  58. package/final-documentation/The Basics/Controllers.md +96 -0
  59. package/final-documentation/The Basics/Error-handling.md +102 -0
  60. package/final-documentation/The Basics/JCC-Blade.md +330 -0
  61. package/final-documentation/The Basics/Middleware.md +174 -0
  62. package/final-documentation/The Basics/Request.md +178 -0
  63. package/final-documentation/The Basics/Response.md +58 -0
  64. package/final-documentation/The Basics/Routing.md +322 -0
  65. package/final-documentation/The Basics/Session.md +97 -0
  66. package/final-documentation/The Basics/Validation.md +235 -0
  67. package/final-documentation/The Basics/Views.md +87 -0
  68. package/lib/Auth/AuthMiddleware.d.ts.map +1 -1
  69. package/lib/Auth/AuthMiddleware.js +13 -6
  70. package/lib/Cache/index.d.ts +2 -0
  71. package/lib/Cache/index.d.ts.map +1 -1
  72. package/lib/Cache/index.js +101 -6
  73. package/lib/Command-Line/NodeArtisanCommand.d.ts +5 -0
  74. package/lib/Command-Line/NodeArtisanCommand.d.ts.map +1 -1
  75. package/lib/Command-Line/NodeArtisanCommand.js +52 -1
  76. package/lib/Command-Line/WatchCommand.d.ts +12 -2
  77. package/lib/Command-Line/WatchCommand.d.ts.map +1 -1
  78. package/lib/Command-Line/WatchCommand.js +186 -45
  79. package/lib/Error/AppErrorHandler.d.ts.map +1 -1
  80. package/lib/Error/AppErrorHandler.js +4 -0
  81. package/lib/Error/ModelExceptions/ModelTokenError.d.ts +4 -0
  82. package/lib/Error/ModelExceptions/ModelTokenError.d.ts.map +1 -0
  83. package/lib/Error/ModelExceptions/ModelTokenError.js +10 -0
  84. package/lib/Http/index.d.ts +3 -0
  85. package/lib/Http/index.d.ts.map +1 -1
  86. package/lib/Http/index.js +46 -10
  87. package/lib/Jcc-eloquent/lib/Model.d.ts +2 -0
  88. package/lib/Jcc-eloquent/lib/Model.d.ts.map +1 -1
  89. package/lib/Jcc-eloquent/lib/Model.js +13 -1
  90. package/lib/Mail/Manager.d.ts +2 -0
  91. package/lib/Mail/Manager.d.ts.map +1 -1
  92. package/lib/Mail/Manager.js +39 -2
  93. package/lib/Monitor/Collectors/CacheCollector.d.ts +2 -4
  94. package/lib/Monitor/Collectors/CacheCollector.d.ts.map +1 -1
  95. package/lib/Monitor/Collectors/CacheCollector.js +4 -63
  96. package/lib/Monitor/Collectors/CommandCollector.d.ts +3 -4
  97. package/lib/Monitor/Collectors/CommandCollector.d.ts.map +1 -1
  98. package/lib/Monitor/Collectors/CommandCollector.js +3 -4
  99. package/lib/Monitor/Collectors/DatabaseCollector.d.ts +2 -0
  100. package/lib/Monitor/Collectors/DatabaseCollector.d.ts.map +1 -1
  101. package/lib/Monitor/Collectors/DatabaseCollector.js +8 -1
  102. package/lib/Monitor/Collectors/MailCollector.d.ts +2 -4
  103. package/lib/Monitor/Collectors/MailCollector.d.ts.map +1 -1
  104. package/lib/Monitor/Collectors/MailCollector.js +5 -58
  105. package/lib/Monitor/Collectors/OutgoingRequestCollector.d.ts +3 -4
  106. package/lib/Monitor/Collectors/OutgoingRequestCollector.d.ts.map +1 -1
  107. package/lib/Monitor/Collectors/OutgoingRequestCollector.js +6 -8
  108. package/lib/Monitor/Collectors/ScheduleCollector.d.ts +2 -3
  109. package/lib/Monitor/Collectors/ScheduleCollector.d.ts.map +1 -1
  110. package/lib/Monitor/Collectors/ScheduleCollector.js +2 -3
  111. package/lib/Monitor/Controllers/MonitorController.d.ts +1 -0
  112. package/lib/Monitor/Controllers/MonitorController.d.ts.map +1 -1
  113. package/lib/Monitor/Controllers/MonitorController.js +15 -8
  114. package/lib/Monitor/MonitorManager.d.ts +10 -1
  115. package/lib/Monitor/MonitorManager.d.ts.map +1 -1
  116. package/lib/Monitor/MonitorManager.js +39 -1
  117. package/lib/Monitor/MonitorServiceProvider.d.ts.map +1 -1
  118. package/lib/Monitor/MonitorServiceProvider.js +3 -1
  119. package/lib/Monitor/Views/{cache.blade.html → JSBlade/cache.blade.html} +1 -1
  120. package/lib/Monitor/Views/{commands.blade.html → JSBlade/commands.blade.html} +2 -2
  121. package/lib/Monitor/Views/{mail.blade.html → JSBlade/mail.blade.html} +1 -1
  122. package/lib/Monitor/Views/{outgoing.blade.html → JSBlade/outgoing.blade.html} +1 -1
  123. package/lib/Monitor/Views/{queries.blade.html → JSBlade/queries.blade.html} +6 -0
  124. package/lib/Monitor/Views/{requests.blade.html → JSBlade/requests.blade.html} +13 -3
  125. package/lib/Monitor/Views/{scheduled.blade.html → JSBlade/scheduled.blade.html} +1 -1
  126. package/lib/Monitor/Views/React/Cache.jsx +29 -0
  127. package/lib/Monitor/Views/React/Commands.jsx +28 -0
  128. package/lib/Monitor/Views/React/Dashboard.jsx +72 -0
  129. package/lib/Monitor/Views/React/Exceptions.jsx +38 -0
  130. package/lib/Monitor/Views/React/Jobs.jsx +29 -0
  131. package/lib/Monitor/Views/React/Logs.jsx +54 -0
  132. package/lib/Monitor/Views/React/Mail.jsx +29 -0
  133. package/lib/Monitor/Views/React/MonitorLayout.jsx +94 -0
  134. package/lib/Monitor/Views/React/Notifications.jsx +28 -0
  135. package/lib/Monitor/Views/React/Outgoing.jsx +28 -0
  136. package/lib/Monitor/Views/React/Queries.jsx +70 -0
  137. package/lib/Monitor/Views/React/Requests.jsx +34 -0
  138. package/lib/Monitor/Views/React/Scheduled.jsx +28 -0
  139. package/lib/Monitor/Views/React/Sidebar.jsx +108 -0
  140. package/lib/Monitor/Views/React/ui.jsx +176 -0
  141. package/lib/Monitor/Views/React/useTheme.js +69 -0
  142. package/lib/Monitor/Views/Vue/Cache.vue +38 -0
  143. package/lib/Monitor/Views/Vue/Commands.vue +37 -0
  144. package/lib/Monitor/Views/Vue/Dashboard.vue +87 -0
  145. package/lib/Monitor/Views/Vue/DataTable.vue +116 -0
  146. package/lib/Monitor/Views/Vue/EmptyState.vue +18 -0
  147. package/lib/Monitor/Views/Vue/Exceptions.vue +43 -0
  148. package/lib/Monitor/Views/Vue/Jobs.vue +38 -0
  149. package/lib/Monitor/Views/Vue/Logs.vue +58 -0
  150. package/lib/Monitor/Views/Vue/Mail.vue +38 -0
  151. package/lib/Monitor/Views/Vue/MethodBadge.vue +8 -0
  152. package/lib/Monitor/Views/Vue/MonitorLayout.vue +80 -0
  153. package/lib/Monitor/Views/Vue/Notifications.vue +37 -0
  154. package/lib/Monitor/Views/Vue/Outgoing.vue +38 -0
  155. package/lib/Monitor/Views/Vue/Panel.vue +18 -0
  156. package/lib/Monitor/Views/Vue/Queries.vue +68 -0
  157. package/lib/Monitor/Views/Vue/Requests.vue +49 -0
  158. package/lib/Monitor/Views/Vue/Scheduled.vue +37 -0
  159. package/lib/Monitor/Views/Vue/Sidebar.vue +98 -0
  160. package/lib/Monitor/Views/Vue/StateBadge.vue +25 -0
  161. package/lib/Monitor/Views/Vue/StatusBadge.vue +17 -0
  162. package/lib/Monitor/Views/Vue/format.js +31 -0
  163. package/lib/Monitor/Views/Vue/useTheme.js +71 -0
  164. package/lib/Monitor/index.d.ts +1 -0
  165. package/lib/Monitor/index.d.ts.map +1 -1
  166. package/lib/Monitor/index.js +1 -0
  167. package/lib/Monitor/types.d.ts +3 -1
  168. package/lib/Monitor/types.d.ts.map +1 -1
  169. package/lib/Monitor/types.js +13 -2
  170. package/lib/Queue/Queue.d.ts +4 -0
  171. package/lib/Queue/Queue.d.ts.map +1 -1
  172. package/lib/Queue/Queue.js +55 -0
  173. package/lib/Schedule/Scheduler.d.ts +2 -0
  174. package/lib/Schedule/Scheduler.d.ts.map +1 -1
  175. package/lib/Schedule/Scheduler.js +28 -1
  176. package/lib/Server/index.d.ts +2 -0
  177. package/lib/Server/index.d.ts.map +1 -1
  178. package/lib/Server/index.js +12 -1
  179. package/lib/Templating-engine/engineHelper.d.ts +2 -2
  180. package/lib/Templating-engine/engineHelper.d.ts.map +1 -1
  181. package/lib/Templating-engine/engineHelper.js +5 -2
  182. package/package.json +1 -1
  183. /package/lib/Monitor/Views/{dashboard.blade.html → JSBlade/dashboard.blade.html} +0 -0
  184. /package/lib/Monitor/Views/{exceptions.blade.html → JSBlade/exceptions.blade.html} +0 -0
  185. /package/lib/Monitor/Views/{jobs.blade.html → JSBlade/jobs.blade.html} +0 -0
  186. /package/lib/Monitor/Views/{logs.blade.html → JSBlade/logs.blade.html} +0 -0
  187. /package/lib/Monitor/Views/{notifications.blade.html → JSBlade/notifications.blade.html} +0 -0
  188. /package/lib/Monitor/Views/{partials → JSBlade/partials}/empty-state.blade.html +0 -0
  189. /package/lib/Monitor/Views/{partials → JSBlade/partials}/sidebar.blade.html +0 -0
  190. /package/lib/Monitor/Views/{partials → JSBlade/partials}/top-header.blade.html +0 -0
@@ -0,0 +1,137 @@
1
+ # Request lifecycle
2
+
3
+ ## Introduction
4
+
5
+ When you use any tool in the real world, you work with more confidence when you understand how that tool works. Building applications is no different. When you know how your framework handles an HTTP request, you feel more comfortable choosing middleware, debugging routes, and structuring `app/` and `route/`.
6
+
7
+ This document gives a high-level picture of how JCC Express MVC works: Express.js underneath, with a Laravel-inspired service container, HTTP kernel, service providers, and routing.
8
+
9
+ ---
10
+
11
+ ## Lifecycle overview
12
+
13
+ At the highest level:
14
+
15
+ ```text
16
+ Web server / reverse proxy
17
+ → Node runs server.ts
18
+ → bootstrap/app builds the Application (container + config + providers + kernel + middleware)
19
+ → app.run() loads routes into RouteBuilder, then listens on PORT
20
+ → Each request: Express middleware stack → kernel middleware → container binds req/res
21
+ → Router matches route → route middleware → controller or closure → response
22
+ → Response finishes; per-request container bindings are cleared
23
+ ```
24
+
25
+ ---
26
+
27
+ ## First steps
28
+
29
+ ### The entry point
30
+
31
+ The entry point for the HTTP application is `server.ts` at the project root (not `public/index.php` like PHP Laravel—your reverse proxy forwards to the Node/Bun process). `server.ts` is small: it imports the application from `bootstrap/app` and calls `app.run()`.
32
+
33
+ ```typescript
34
+ import { app } from "./bootstrap/app";
35
+ app.run();
36
+ ```
37
+
38
+ ### Loading the application
39
+
40
+ `bootstrap/app.ts` builds an `Application` instance through `Application.configuration()`—a builder that wires routing, `app/Config`, service providers, `app/Http/kernel`, and global middleware, then `.create()`. That returns the same `app` you import in `server.ts`.
41
+
42
+ The first structural object the framework gives you is this Application: it acts as the service container (bind / resolve services) and wraps the Express app used for HTTP.
43
+
44
+ ---
45
+
46
+ ## HTTP kernel
47
+
48
+ In Laravel, the HTTP kernel is `Illuminate\Foundation\Http\Kernel`. In JCC Express MVC, the equivalent is `app/Http/kernel.ts`: a class registered as `HttpKernel` whose `middlewares` array becomes part of the global Express pipeline.
49
+
50
+ The kernel is the central place through which every web request passes after the framework’s own Express setup (body parsers, session, CORS, logging, rate limiting, `HttpRequest` / `HttpResponse`, etc.) and before your routes run.
51
+
52
+ The kernel also declares `middlewareAliases`—short names like `auth`, `guest`, or throttles—that you attach per route with `Route.middleware(['auth'])`.
53
+
54
+ Think of the stack as: framework defaults → your kernel `middlewares` (for example CSRF, method spoofing, Inertia) → route matching → route middleware → handler. The kernel’s job is to define that global slice and the alias map; the `Middleware` class inside `jcc-express-mvc` applies the full chain to Express when the app is built.
55
+
56
+ ---
57
+
58
+ ## Service providers
59
+
60
+ One of the most important bootstrap steps is loading service providers. Providers register bindings on the container (`register`) and run extra setup once registrations exist (`boot`).
61
+
62
+ In `ApplicationBuilder.withProviders()`, the framework prepends `DatabaseServiceProvider`, registers your list from `bootstrap/providers.ts` (and may place `AuthServiceProvider` early), then appends `QueueServiceProvider`. That order matters so the database, auth, and queue subsystems are available where other code expects them.
63
+
64
+ Your own providers live under `app/Providers/` (for example `AppServiceProvider`) and are listed in `bootstrap/providers.ts`. Use `AppServiceProvider` (or additional providers) for container bindings, config-driven setup, and small bootstrap tasks—same idea as Laravel’s `AppServiceProvider`.
65
+
66
+ Most “big” features (database, queues, routing registration, events) are tied to framework or app providers. Understanding register vs boot helps when something is “not bound yet” during startup.
67
+
68
+ ---
69
+
70
+ ## Routing
71
+
72
+ After the application is built and `app.run()` executes:
73
+
74
+ 1. `RouteBuilder` receives the service container.
75
+ 2. `RouteServiceProvider.loadRoutes()` runs each configured route module (for example `route/web`, `route/api`) with the right URL prefix from `bootstrap/app.ts`. Route files call `Route.get`, `Route.post`, etc., which record routes in `RouteBuilder`—they do not yet attach to Express in all setups until the next step.
76
+ 3. `Server` opens `PORT`, then calls `RouteBuilder.registerRoute(expressApp)`, which registers method + path + middleware + handler on Express and wires global error handling.
77
+
78
+ So: providers and kernel configure the app; route files declare endpoints; listening is when those endpoints are mounted on Express.
79
+
80
+ When a request arrives, Express dispatches it to the matching route. The handler may be a closure or a controller method resolved from the container.
81
+
82
+ ---
83
+
84
+ ## Middleware
85
+
86
+ Middleware filters or inspects the request (and sometimes the response path). Examples:
87
+
88
+ - Global middleware—applied to every request—includes the framework stack (JSON, session, CORS, …) plus `Kernel.middlewares` (CSRF, Inertia, …).
89
+ - Route middleware—only on routes that name it—uses `Kernel.middlewareAliases` (`auth`, `guest`, …).
90
+
91
+ If the request fails a guard (for example user not authenticated), middleware can redirect or abort before your controller runs.
92
+
93
+ If the request passes all matched middleware, your route or controller runs and produces the response (JSON, Blade, Inertia, redirect, …).
94
+
95
+ Reference — framework middleware order (before kernel entries), from `jcc-express-mvc/lib/Middleware`:
96
+
97
+ 1. `express.json()`
98
+ 2. `express.urlencoded({ extended: false })`
99
+ 3. `cookie-parser()`
100
+ 4. `express-session`
101
+ 5. `connect-flash`
102
+ 6. `express-fileupload`
103
+ 7. CORS (`app.config.cors`)
104
+ 8. Morgan (format depends on `APP_DEBUG`)
105
+ 9. Rate limit (`app.config.rateLimit`)
106
+ 10. `HttpRequest` / `HttpResponse` and `jccSession` on `req`
107
+
108
+ Then `Kernel.middlewares` runs in array order. After that, middleware binds `request`, `response`, and `next` on the container for helpers like `view()` and `inertia()`.
109
+
110
+ Inertia: visits with the `X-Inertia` header receive a JSON page payload; full page loads get HTML from the root Blade view. The same route handler often serves both; Inertia middleware and `res.inertia` handle the difference.
111
+
112
+ ---
113
+
114
+ ## Finishing up
115
+
116
+ When your controller or closure finishes—by calling `res.send`, `res.json`, `res.render`, `view()`, `res.inertia`, `inertia()`, `redirect()`, `res.inertiaRedirect()`, or returning a value the route wrapper turns into JSON—Express ends the response.
117
+
118
+ The framework listens for `finish` on the response and clears the per-request `request` / `response` / `next` bindings on the container so the next request does not leak state.
119
+
120
+ If an error is passed to `next(error)` or thrown without being caught, `AppErrorHandler` maps it to an HTTP response (status and body) according to framework rules.
121
+
122
+ ---
123
+
124
+ ## Focus on service providers
125
+
126
+ Service providers are the main lever for bootstrapping a JCC Express MVC application: the Application is created, providers `register` and `boot`, routes are loaded and registered, then requests hit the kernel and router.
127
+
128
+ Your `bootstrap/providers.ts` list is the counterpart to Laravel’s provider list—keep it focused: put general bindings in `AppServiceProvider`, and add more providers when a feature needs its own `register`/`boot` block.
129
+
130
+ ---
131
+
132
+ ## Where to customize (quick reference)
133
+
134
+ - Global HTTP middleware — `app/Http/kernel.ts` → `middlewares` and `middlewareAliases`.
135
+ - Default Express stack — `jcc-express-mvc/lib/Middleware` + `app/Config` (CORS, rate limit, engine).
136
+ - Routes and API prefixes — `route/*.ts` and `bootstrap/app.ts` → `withRouting`.
137
+ - Container bindings and boot logic — `app/Providers/*` and `bootstrap/providers.ts`.
@@ -0,0 +1,134 @@
1
+ # Service container
2
+
3
+ ## Introduction
4
+
5
+ The service container is a registry for creating and retrieving objects in your application. Instead of constructing dependencies by hand in every controller or route, you bind how something should be built once, then resolve it whenever you need it—similar in spirit to Laravel’s container.
6
+
7
+ In JCC Express MVC, the `Application` class is the container: it extends `ExpressApplication`, which extends `Container` from `jcc-express-mvc`. When `bootstrap/app` finishes building, you have a single `app` object that is both the Express app owner and the dependency injection hub.
8
+
9
+ ---
10
+
11
+ ## Why use a container
12
+
13
+ - One place to wire implementations (interfaces → concrete classes, factories, config).
14
+ - Singletons for expensive or shared services (database, cache clients, queues).
15
+ - Request-scoped values (`request`, `response`, `next`) registered per HTTP request and cleared when the response ends.
16
+ - Constructor injection where `reflect-metadata` can resolve parameter types from the container (used in parts of the framework and advanced app code).
17
+
18
+ ---
19
+
20
+ ## Core API
21
+
22
+ Bindings are keyed by string (for example `"TestingService"`) or by class / constructor name when using `make()` / `build()`.
23
+
24
+ ### `bind(abstract, concrete, shared?)`
25
+
26
+ Registers how to build a service. `concrete` may be:
27
+
28
+ - A class — instantiated with optional constructor injection.
29
+ - A factory function `(container) => instance` — you control creation.
30
+
31
+ If `shared` is `true`, the first resolved instance may be cached (singleton behavior for that binding).
32
+
33
+ ### `singleton(abstract, concrete)`
34
+
35
+ Ensures a binding exists and marks it shared so `resolve` returns the same instance afterward (typical for app-wide services).
36
+
37
+ ### `instance(abstract, object)`
38
+
39
+ Registers a ready-made object under a key. Used for:
40
+
41
+ - `app.instance("app", this)` in `Application`’s constructor.
42
+ - `app.instance("request", req)` / `response` / `next` during a request (see `Middleware` in `jcc-express-mvc`).
43
+
44
+ ### `resolve(abstract, parameters?, callFactory?)`
45
+
46
+ Returns an instance: checks instances map, aliases, then bindings, and may `build` a class with injected dependencies.
47
+
48
+ ### `make(Class, params?)`
49
+
50
+ Registers the class name if needed and `resolve`s it—handy for on-the-fly resolution.
51
+
52
+ ### `alias(alias, abstract)`
53
+
54
+ Lets you `resolve` using an alternate name pointing at the same binding.
55
+
56
+ ### `has(abstract)`
57
+
58
+ Returns whether a binding, instance, or alias exists.
59
+
60
+ ### `forget(abstract)` / `forgetMany(keys[])`
61
+
62
+ Removes instances (and related alias keys). The framework uses `forgetMany(["request", "response", "next"])` after each response `finish` so the next request does not reuse stale `req`/`res`.
63
+
64
+ ---
65
+
66
+ ## Where bindings come from
67
+
68
+ 1. Framework constructor — `Application` registers `app`, `RouteServiceProvider`, `Event`, etc.
69
+ 2. `ExpressApplication` — Binds `express`, `expressApp`, `httpListen`, `socketIo`, etc.
70
+ 3. Service providers — In `register()`, call `this.app.bind(...)` / `singleton(...)`. See `app/Providers/AppServiceProvider.ts` and `bootstrap/providers.ts`.
71
+ 4. HTTP pipeline — Middleware puts `request`, `response`, `next` on the container for the current request.
72
+ 5. Your code — Anywhere you have `app`, you can bind services at startup or (less often) at runtime.
73
+
74
+ ---
75
+
76
+ ## Dependency injection on constructors
77
+
78
+ `Container.build()` uses `reflect-metadata` (`design:paramtypes`) to guess constructor parameters and `resolve` them by type name. This works when:
79
+
80
+ - `emitDecoratorMetadata` is enabled in `tsconfig.json` (your project has it).
81
+ - Parameter types are classes or names the container knows.
82
+
83
+ If resolution fails, you may need an explicit `bind` for that type or pass parameters into `resolve`.
84
+
85
+ ---
86
+
87
+ ## Controllers and `callControllerMethod`
88
+
89
+ For controller actions, the framework can `callControllerMethod`, which reads `inject:method:deps` metadata and resolves FormRequest, models, route parameters, etc. Plain routes that use `(req, res) =>` do not need this—you still benefit from `view()` / `inertia()` because they read `response` from the container after it is bound.
90
+
91
+ ---
92
+
93
+ ## Global `app` and helpers
94
+
95
+ After `globalHelpers(app)` runs (during `ApplicationBuilder.create()`), `globalThis.app` is the Application instance. Helpers like `env()`, `view()`, `inertia()` use the container under the hood (for example `response` from `app.resolve("response")`).
96
+
97
+ Prefer constructor injection or explicit `app.resolve()` in providers and long-lived services; use globals where the framework already does (routes, Blade/Inertia helpers).
98
+
99
+ ---
100
+
101
+ ## Comparison to Laravel (mental model)
102
+
103
+ - Container class — Laravel: `Illuminate\Container\Container`. JCC: `jcc-express-mvc/lib/Container`.
104
+ - Application — Laravel’s `Application` extends the container. JCC: `Application` → `ExpressApplication` → `Container`.
105
+ - Registering services — Laravel: `AppServiceProvider::register`. JCC: same idea in `app/Providers/*` → `register()`.
106
+ - Resolving — Laravel: `app()`, `resolve()`. JCC: `app.resolve()`, `app.make()`.
107
+ - Current HTTP request — Laravel: type-hint `Request`. JCC: `instance("request", req)` (and `response` / `next`) per request.
108
+
109
+ ---
110
+
111
+ ## Practical pattern in a provider
112
+
113
+ ```typescript
114
+ // app/Providers/AppServiceProvider.ts (conceptual)
115
+ import { ServiceProvider } from "jcc-express-mvc/Core/Provider";
116
+
117
+ export class AppServiceProvider extends ServiceProvider {
118
+ register(): void {
119
+ this.app.singleton("MyApiClient", () => {
120
+ return new MyApiClient(env("API_URL") ?? "");
121
+ });
122
+ }
123
+
124
+ async boot(): Promise<void> {
125
+ // use other bindings, gates, events, …
126
+ }
127
+ }
128
+ ```
129
+
130
+ Elsewhere:
131
+
132
+ ```typescript
133
+ const client = app.resolve<MyApiClient>("MyApiClient");
134
+ ```
@@ -0,0 +1,105 @@
1
+ # Service providers
2
+
3
+ ## Introduction
4
+
5
+ Service providers are the main way to bootstrap features in JCC Express MVC. Each provider is a class that receives the `Application` (the service container) and uses `register()` to bind services and `boot()` to run logic after all providers have registered—mirroring Laravel’s register / boot split.
6
+
7
+ Listing providers in `bootstrap/providers.ts` and implementing them under `app/Providers/` keeps startup explicit and ordered.
8
+
9
+ ---
10
+
11
+ ## What a provider does
12
+
13
+ A provider connects the framework to your app:
14
+
15
+ - Register container bindings (`bind`, `singleton`, `instance`) so other code can `resolve` them.
16
+ - Boot behavior that depends on those bindings (routes are not registered here—`RouteServiceProvider` loads route files during `app.run()`, but your `boot()` can use `Gate`, events, or other services already on the container).
17
+
18
+ The abstract base class lives in `jcc-express-mvc` (`ServiceProvider`). Extend it from `jcc-express-mvc/Core/Provider` (re-export) or the underlying `lib/Providers/ServiceProvider`.
19
+
20
+ ---
21
+
22
+ ## The `ServiceProvider` base class
23
+
24
+ - `constructor(protected app: Application)` — Stores the application instance as `this.app`.
25
+ - `abstract register(): void` — You must implement this. Put container registrations here only; avoid resolving services that other providers have not registered yet.
26
+ - `boot(): void | Promise<void>` — Optional override. Runs after every provider’s `register()` has completed (see When `register` and `boot` run). Use for `Gate.define`, subscribing to events, or resolving bindings that need the full container.
27
+ - `listen` / `subscribe` — Optional maps used when `bootListeners` or `bootSubscribers` is set on the provider so the `Application` wires event listeners or subscribers during registration.
28
+
29
+ ---
30
+
31
+ ## Registration order (`ApplicationBuilder`)
32
+
33
+ In `withProviders()`, the builder does not use your array alone. It builds this chain:
34
+
35
+ 1. `DatabaseServiceProvider` — Always first (database-related setup).
36
+ 2. Your providers from `bootstrap/providers.ts` — If `AuthServiceProvider` (framework) is in the list but not first, the builder moves it to the front of your list so auth is set up early.
37
+ 3. `QueueServiceProvider` — Always last in the chain.
38
+
39
+ That order matters when one provider’s `register()` assumes another binding already exists.
40
+
41
+ ---
42
+
43
+ ## When `register` and `boot` run
44
+
45
+ During `bootstrap/app` build:
46
+
47
+ - For each provider class in the chain, `new Provider(app)` is called, then `register()` runs immediately.
48
+ - If the provider sets `bootSubscribers` / `bootListeners`, the app may call `subscribers()` / `listeners()` right after that provider registers.
49
+
50
+ `boot()` for all providers:
51
+
52
+ - When `app.boot()` runs (for example from `app.run()` if the app was not yet booted), the application loops `this.providers` and calls `boot()` on each in registration order.
53
+
54
+ Late registration:
55
+
56
+ - If a provider is registered after the application is already `booted`, `register()` still runs, and `bootProvider` is invoked immediately for that provider so it does not miss the boot phase.
57
+
58
+ ---
59
+
60
+ ## Writing a provider
61
+
62
+ 1. Create a class under `app/Providers/` extending `ServiceProvider`.
63
+ 2. Implement `register()` with `this.app.bind`, `singleton`, etc.
64
+ 3. Override `boot()` when you need work after all `register()` methods have finished.
65
+ 4. Add the class to the `providers` array exported from `bootstrap/providers.ts` (already imported by `bootstrap/app.ts` via `withProviders`).
66
+
67
+ Keep `register()` free of heavy side effects and of `resolve()` calls that depend on providers later in the chain unless you know the order.
68
+
69
+ ---
70
+
71
+ ## Example
72
+
73
+ ```typescript
74
+ // app/Providers/AppServiceProvider.ts
75
+ import { ServiceProvider } from "jcc-express-mvc/Core/Provider";
76
+
77
+ export class AppServiceProvider extends ServiceProvider {
78
+ register(): void {
79
+ this.app.singleton("Billing", () => new BillingService());
80
+ }
81
+
82
+ async boot(): Promise<void> {
83
+ const billing = this.app.resolve<BillingService>("Billing");
84
+ // configure billing from config, register policies, etc.
85
+ }
86
+ }
87
+ ```
88
+
89
+ ```typescript
90
+ // bootstrap/providers.ts
91
+ import { AppServiceProvider } from "../app/Providers/AppServiceProvider";
92
+
93
+ export const providers = [AppServiceProvider];
94
+ ```
95
+
96
+ ---
97
+
98
+ ## Framework providers you should know about
99
+
100
+ - `DatabaseServiceProvider` — Database / ORM wiring; runs before your list.
101
+ - `AuthServiceProvider` (when included) — Intended to run early among your providers.
102
+ - `QueueServiceProvider` — Queue binding; runs after your list.
103
+ - `RouteServiceProvider` — Not in your `bootstrap/providers.ts` list by default; it is registered as a singleton on `Application` and `loadRoutes()` is invoked from `app.run()` to load `route/web`, `route/api`, etc.
104
+
105
+ Your `AppServiceProvider` (and any custom providers) are where application-specific bindings and `boot` logic belong.
@@ -0,0 +1,240 @@
1
+ # Database: Getting Started
2
+
3
+ ## Introduction
4
+
5
+ Almost every real application needs a database. JCC Express MVC keeps this flexible by supporting:
6
+
7
+ - **JCC ORM (default)** for SQL with a Knex-backed query layer
8
+ - **Sequelize** as an alternative SQL ORM
9
+ - **Mongoose** for MongoDB document workflows
10
+
11
+ In practice, most projects start with the default JCC stack, then switch ORM mode only when needed.
12
+
13
+ ---
14
+
15
+ ## Supported database engines
16
+
17
+ With the default JCC SQL path (`DB_ORM=jcc`), connection clients include:
18
+
19
+ - `mysql2`
20
+ - `postgres`
21
+ - `sqlite`
22
+ - `better-sqlite3`
23
+
24
+ For document databases, use `DB_ORM=mongoose` with your Mongo connection settings.
25
+
26
+ ---
27
+
28
+ ## Configuration
29
+
30
+ Database settings live in your app config and environment values:
31
+
32
+ - `app/Config/database.ts`
33
+ - `app/Config/index.ts` (exports `database`)
34
+ - `.env` values such as `DB_ORM`, `DB_CONNECTION`, `DB_HOST`, `DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`
35
+
36
+ Minimal shape from `app/Config/database.ts`:
37
+
38
+ ```typescript
39
+ export const database = {
40
+ orm: config.get("DB_ORM", "jcc"),
41
+ sequelize: { /* ... */ },
42
+ mongoose: { /* ... */ },
43
+ };
44
+ ```
45
+
46
+ ---
47
+
48
+ ## SQLite configuration
49
+
50
+ For SQLite style connections (`sqlite` or `better-sqlite3`), the default JCC database layer resolves to a file database (`db.sqlite`) at project root.
51
+
52
+ Typical env setup:
53
+
54
+ ```env
55
+ DB_ORM=jcc
56
+ DB_CONNECTION=sqlite
57
+ DB_DATABASE=db.sqlite
58
+ ```
59
+
60
+ If you need a different file location, align your adapter/config with your deployment path strategy.
61
+
62
+ ---
63
+
64
+ ## Choosing ORM mode
65
+
66
+ The provider layer uses your env/config to decide connection behavior:
67
+
68
+ - `DB_ORM=jcc` -> JCC/Knex SQL flow
69
+ - `DB_ORM=sequelize` -> Sequelize connection path
70
+ - `DB_ORM=mongoose` -> Mongoose connection path
71
+
72
+ Keep `DB_ORM` and `DB_CONNECTION` consistent (for example, do not pair `DB_ORM=mongoose` with SQL-only assumptions in your app code).
73
+
74
+ ---
75
+
76
+ ## Running queries
77
+
78
+ ### Query builder style
79
+
80
+ ```typescript
81
+ const users = await DB.table("users").get();
82
+ const user = await DB.table("users").where("id", 1).first();
83
+ ```
84
+
85
+ ### Raw SQL
86
+
87
+ ```typescript
88
+ const rows = await DB.runQuery("select * from users where active = ?", [1]);
89
+ ```
90
+
91
+ Or:
92
+
93
+ ```typescript
94
+ const raw = DB.raw("select count(*) as total from users");
95
+ ```
96
+
97
+ Use bound parameters (`?`) instead of string interpolation to reduce SQL injection risk.
98
+
99
+ ---
100
+
101
+ ## More method usage examples
102
+
103
+ ### Inserts
104
+
105
+ ```typescript
106
+ await DB.table("users").insert({
107
+ name: "Abdou",
108
+ email: "abdou@example.com",
109
+ });
110
+ ```
111
+
112
+ ### Updates
113
+
114
+ ```typescript
115
+ await DB.table("users").where("id", 1).update({
116
+ name: "Abdou J",
117
+ });
118
+ ```
119
+
120
+ ### Deletes
121
+
122
+ ```typescript
123
+ await DB.table("users").where("id", 1).delete();
124
+ ```
125
+
126
+ ### Filtering and ordering
127
+
128
+ ```typescript
129
+ const activeUsers = await DB.table("users")
130
+ .where("active", true)
131
+ .orderBy("created_at", "desc")
132
+ .limit(20)
133
+ .get();
134
+ ```
135
+
136
+ ### Column selection
137
+
138
+ ```typescript
139
+ const slim = await DB.table("users")
140
+ .select("id", "name", "email")
141
+ .where("active", true)
142
+ .get();
143
+ ```
144
+
145
+ ### Counting and aggregates
146
+
147
+ ```typescript
148
+ const totalUsers = await DB.table("users").count("id as total");
149
+ const maxScore = await DB.table("users").max("score as max_score");
150
+ const avgScore = await DB.table("users").avg("score as avg_score");
151
+ ```
152
+
153
+ ### Pagination (offset/limit style)
154
+
155
+ ```typescript
156
+ const page = 2;
157
+ const perPage = 15;
158
+
159
+ const rows = await DB.table("users")
160
+ .offset((page - 1) * perPage)
161
+ .limit(perPage)
162
+ .get();
163
+ ```
164
+
165
+ ### Conditional create/update patterns
166
+
167
+ ```typescript
168
+ const exists = await DB.table("users").where("email", email).exists();
169
+
170
+ if (!exists) {
171
+ await DB.table("users").insert({ email, name });
172
+ } else {
173
+ await DB.table("users").where("email", email).update({ name });
174
+ }
175
+ ```
176
+
177
+ ### Raw expression inside builder
178
+
179
+ ```typescript
180
+ const report = await DB.table("orders")
181
+ .select("status")
182
+ .select(DB.raw("count(*) as total"))
183
+ .groupBy("status")
184
+ .get();
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Transactions
190
+
191
+ JCC DB supports transaction wrappers:
192
+
193
+ ```typescript
194
+ await DB.transaction(async () => {
195
+ await DB.table("users").insert({ name: "Abdou" });
196
+ await DB.table("profiles").insert({ user_id: 1 });
197
+ });
198
+ ```
199
+
200
+ Keep schema-altering or implicit-commit statements out of transactional write flows unless you fully understand your database engine behavior.
201
+
202
+ ---
203
+
204
+ ## Migrations and seeders
205
+
206
+ Use ArtisanNode for schema and seed lifecycle:
207
+
208
+ ```bash
209
+ bun artisanNode make:migration create_users_table
210
+ bun artisanNode migrate
211
+ bun artisanNode migrate:rollback
212
+ bun artisanNode migrate:reset
213
+ bun artisanNode migrate:fresh
214
+ bun artisanNode db:seed
215
+ bun artisanNode db:wipe
216
+ ```
217
+
218
+ Queue tables:
219
+
220
+ ```bash
221
+ bun artisanNode make:queue-table
222
+ bun artisanNode migrate
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Practical recommendations
228
+
229
+ - Start with the default JCC stack unless a project requirement mandates Sequelize or Mongoose.
230
+ - Keep migrations in version control and run them in CI/CD.
231
+ - Prefer parameterized queries over manual string building.
232
+ - Validate production env values (`DB_ORM`, credentials, host/port) early in deployment.
233
+
234
+ ---
235
+
236
+ ## Summary
237
+
238
+ - JCC gives you one database entry point with multiple ORM backends.
239
+ - Config is env-driven and centered in `app/Config/database.ts`.
240
+ - Use `DB.table(...)`, `DB.runQuery(...)`, and migrations/seeders for day-to-day database work.