@quvel-kit/core 1.1.0

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 (285) hide show
  1. package/README.md +670 -0
  2. package/dist/auth/boot/defineAuthGuard.d.ts +54 -0
  3. package/dist/auth/boot/defineAuthGuard.d.ts.map +1 -0
  4. package/dist/auth/boot/defineAuthGuard.js +72 -0
  5. package/dist/auth/enums/AuthStatusEnum.d.ts +13 -0
  6. package/dist/auth/enums/AuthStatusEnum.d.ts.map +1 -0
  7. package/dist/auth/enums/AuthStatusEnum.js +13 -0
  8. package/dist/auth/index.d.ts +13 -0
  9. package/dist/auth/index.d.ts.map +1 -0
  10. package/dist/auth/index.js +13 -0
  11. package/dist/auth/services/AuthGuard.d.ts +58 -0
  12. package/dist/auth/services/AuthGuard.d.ts.map +1 -0
  13. package/dist/auth/services/AuthGuard.js +51 -0
  14. package/dist/auth/services/AuthService.d.ts +52 -0
  15. package/dist/auth/services/AuthService.d.ts.map +1 -0
  16. package/dist/auth/services/AuthService.js +67 -0
  17. package/dist/auth/services/PasswordResetService.d.ts +34 -0
  18. package/dist/auth/services/PasswordResetService.d.ts.map +1 -0
  19. package/dist/auth/services/PasswordResetService.js +45 -0
  20. package/dist/auth/services/TwoFactorChallengeService.d.ts +22 -0
  21. package/dist/auth/services/TwoFactorChallengeService.d.ts.map +1 -0
  22. package/dist/auth/services/TwoFactorChallengeService.js +29 -0
  23. package/dist/auth/services/TwoFactorService.d.ts +64 -0
  24. package/dist/auth/services/TwoFactorService.d.ts.map +1 -0
  25. package/dist/auth/services/TwoFactorService.js +68 -0
  26. package/dist/auth/services/index.d.ts +8 -0
  27. package/dist/auth/services/index.d.ts.map +1 -0
  28. package/dist/auth/services/index.js +5 -0
  29. package/dist/auth/types/auth-meta.d.ts +54 -0
  30. package/dist/auth/types/auth-meta.d.ts.map +1 -0
  31. package/dist/auth/types/auth-meta.js +6 -0
  32. package/dist/auth/types/index.d.ts +5 -0
  33. package/dist/auth/types/index.d.ts.map +1 -0
  34. package/dist/auth/types/index.js +4 -0
  35. package/dist/auth/utils/auth-meta.d.ts +75 -0
  36. package/dist/auth/utils/auth-meta.d.ts.map +1 -0
  37. package/dist/auth/utils/auth-meta.js +93 -0
  38. package/dist/boot/quvel.d.ts +26 -0
  39. package/dist/boot/quvel.d.ts.map +1 -0
  40. package/dist/boot/quvel.js +38 -0
  41. package/dist/build/index.d.ts +9 -0
  42. package/dist/build/index.d.ts.map +1 -0
  43. package/dist/build/index.js +8 -0
  44. package/dist/build/loadEnv.d.ts +14 -0
  45. package/dist/build/loadEnv.d.ts.map +1 -0
  46. package/dist/build/loadEnv.js +33 -0
  47. package/dist/build/quasarConfig.d.ts +67 -0
  48. package/dist/build/quasarConfig.d.ts.map +1 -0
  49. package/dist/build/quasarConfig.js +126 -0
  50. package/dist/components/Common/TaskErrors.vue +47 -0
  51. package/dist/components/Inputs/BaseInput.vue +88 -0
  52. package/dist/components/Misc/ClientOnly.vue +22 -0
  53. package/dist/components/Transitions/FadeInOut.vue +9 -0
  54. package/dist/components/Transitions/SlowExpand.vue +13 -0
  55. package/dist/components/WebSocketChannelManager.vue +634 -0
  56. package/dist/components/index.d.ts +12 -0
  57. package/dist/components/index.d.ts.map +1 -0
  58. package/dist/components/index.js +16 -0
  59. package/dist/composables/index.d.ts +19 -0
  60. package/dist/composables/index.d.ts.map +1 -0
  61. package/dist/composables/index.js +16 -0
  62. package/dist/composables/useClient.d.ts +16 -0
  63. package/dist/composables/useClient.d.ts.map +1 -0
  64. package/dist/composables/useClient.js +28 -0
  65. package/dist/composables/useMetaConfig.d.ts +14 -0
  66. package/dist/composables/useMetaConfig.d.ts.map +1 -0
  67. package/dist/composables/useMetaConfig.js +77 -0
  68. package/dist/composables/useQueryMessageHandler.d.ts +44 -0
  69. package/dist/composables/useQueryMessageHandler.d.ts.map +1 -0
  70. package/dist/composables/useQueryMessageHandler.js +74 -0
  71. package/dist/composables/useQuvel.d.ts +15 -0
  72. package/dist/composables/useQuvel.d.ts.map +1 -0
  73. package/dist/composables/useQuvel.js +38 -0
  74. package/dist/composables/useRecaptcha.d.ts +35 -0
  75. package/dist/composables/useRecaptcha.d.ts.map +1 -0
  76. package/dist/composables/useRecaptcha.js +87 -0
  77. package/dist/composables/useScopedService.d.ts +18 -0
  78. package/dist/composables/useScopedService.d.ts.map +1 -0
  79. package/dist/composables/useScopedService.js +25 -0
  80. package/dist/composables/useScript.d.ts +25 -0
  81. package/dist/composables/useScript.d.ts.map +1 -0
  82. package/dist/composables/useScript.js +106 -0
  83. package/dist/composables/useUrlQueryHandler.d.ts +38 -0
  84. package/dist/composables/useUrlQueryHandler.d.ts.map +1 -0
  85. package/dist/composables/useUrlQueryHandler.js +76 -0
  86. package/dist/composables/useWebSockets.d.ts +18 -0
  87. package/dist/composables/useWebSockets.d.ts.map +1 -0
  88. package/dist/composables/useWebSockets.js +55 -0
  89. package/dist/composables/useWindowEvent.d.ts +16 -0
  90. package/dist/composables/useWindowEvent.d.ts.map +1 -0
  91. package/dist/composables/useWindowEvent.js +27 -0
  92. package/dist/composables/useXsrf.d.ts +29 -0
  93. package/dist/composables/useXsrf.d.ts.map +1 -0
  94. package/dist/composables/useXsrf.js +59 -0
  95. package/dist/config/QuasarConfigBuilder.d.ts +100 -0
  96. package/dist/config/QuasarConfigBuilder.d.ts.map +1 -0
  97. package/dist/config/QuasarConfigBuilder.js +98 -0
  98. package/dist/config/i18n.d.ts +23 -0
  99. package/dist/config/i18n.d.ts.map +1 -0
  100. package/dist/config/i18n.js +43 -0
  101. package/dist/config/index.d.ts +8 -0
  102. package/dist/config/index.d.ts.map +1 -0
  103. package/dist/config/index.js +7 -0
  104. package/dist/config/moduleTransformer.d.ts +18 -0
  105. package/dist/config/moduleTransformer.d.ts.map +1 -0
  106. package/dist/config/moduleTransformer.js +76 -0
  107. package/dist/config/quvel.d.ts +40 -0
  108. package/dist/config/quvel.d.ts.map +1 -0
  109. package/dist/config/quvel.js +59 -0
  110. package/dist/config/quvel.types.d.ts +59 -0
  111. package/dist/config/quvel.types.d.ts.map +1 -0
  112. package/dist/config/quvel.types.js +6 -0
  113. package/dist/container/ServiceContainer.d.ts +107 -0
  114. package/dist/container/ServiceContainer.d.ts.map +1 -0
  115. package/dist/container/ServiceContainer.js +201 -0
  116. package/dist/container/types/vue.d.ts +9 -0
  117. package/dist/container/types.d.ts +81 -0
  118. package/dist/container/types.d.ts.map +1 -0
  119. package/dist/container/types.js +1 -0
  120. package/dist/i18n/en-US/common.d.ts +19 -0
  121. package/dist/i18n/en-US/common.d.ts.map +1 -0
  122. package/dist/i18n/en-US/common.js +17 -0
  123. package/dist/i18n/en-US/index.d.ts +21 -0
  124. package/dist/i18n/en-US/index.d.ts.map +1 -0
  125. package/dist/i18n/en-US/index.js +4 -0
  126. package/dist/i18n/es-MX/common.d.ts +19 -0
  127. package/dist/i18n/es-MX/common.d.ts.map +1 -0
  128. package/dist/i18n/es-MX/common.js +17 -0
  129. package/dist/i18n/es-MX/index.d.ts +21 -0
  130. package/dist/i18n/es-MX/index.d.ts.map +1 -0
  131. package/dist/i18n/es-MX/index.js +4 -0
  132. package/dist/index.d.ts +54 -0
  133. package/dist/index.d.ts.map +1 -0
  134. package/dist/index.js +67 -0
  135. package/dist/models/User.d.ts +32 -0
  136. package/dist/models/User.d.ts.map +1 -0
  137. package/dist/models/User.js +48 -0
  138. package/dist/module.d.ts +21 -0
  139. package/dist/module.d.ts.map +1 -0
  140. package/dist/module.js +45 -0
  141. package/dist/modules/helpers.d.ts +30 -0
  142. package/dist/modules/helpers.d.ts.map +1 -0
  143. package/dist/modules/helpers.js +45 -0
  144. package/dist/modules/index.d.ts +8 -0
  145. package/dist/modules/index.d.ts.map +1 -0
  146. package/dist/modules/index.js +6 -0
  147. package/dist/modules/types.d.ts +141 -0
  148. package/dist/modules/types.d.ts.map +1 -0
  149. package/dist/modules/types.js +7 -0
  150. package/dist/pages/ErrorNotFound.vue +300 -0
  151. package/dist/pages/index.d.ts +7 -0
  152. package/dist/pages/index.d.ts.map +1 -0
  153. package/dist/pages/index.js +6 -0
  154. package/dist/services/ApiService.d.ts +90 -0
  155. package/dist/services/ApiService.d.ts.map +1 -0
  156. package/dist/services/ApiService.js +159 -0
  157. package/dist/services/I18nService.d.ts +67 -0
  158. package/dist/services/I18nService.d.ts.map +1 -0
  159. package/dist/services/I18nService.js +92 -0
  160. package/dist/services/LogService.d.ts +31 -0
  161. package/dist/services/LogService.d.ts.map +1 -0
  162. package/dist/services/LogService.js +49 -0
  163. package/dist/services/Service.d.ts +10 -0
  164. package/dist/services/Service.d.ts.map +1 -0
  165. package/dist/services/Service.js +8 -0
  166. package/dist/services/TaskService.d.ts +64 -0
  167. package/dist/services/TaskService.d.ts.map +1 -0
  168. package/dist/services/TaskService.js +188 -0
  169. package/dist/services/ThemeService.d.ts +28 -0
  170. package/dist/services/ThemeService.d.ts.map +1 -0
  171. package/dist/services/ThemeService.js +77 -0
  172. package/dist/services/ValidationService.d.ts +55 -0
  173. package/dist/services/ValidationService.d.ts.map +1 -0
  174. package/dist/services/ValidationService.js +81 -0
  175. package/dist/services/WebSocketService.d.ts +59 -0
  176. package/dist/services/WebSocketService.d.ts.map +1 -0
  177. package/dist/services/WebSocketService.js +148 -0
  178. package/dist/services/logger/BaseLogger.d.ts +35 -0
  179. package/dist/services/logger/BaseLogger.d.ts.map +1 -0
  180. package/dist/services/logger/BaseLogger.js +66 -0
  181. package/dist/services/logger/ConsoleLogger.d.ts +21 -0
  182. package/dist/services/logger/ConsoleLogger.d.ts.map +1 -0
  183. package/dist/services/logger/ConsoleLogger.js +60 -0
  184. package/dist/services/logger/NullLogger.d.ts +10 -0
  185. package/dist/services/logger/NullLogger.d.ts.map +1 -0
  186. package/dist/services/logger/NullLogger.js +10 -0
  187. package/dist/stores/plugins/serviceContainer.d.ts +10 -0
  188. package/dist/stores/plugins/serviceContainer.d.ts.map +1 -0
  189. package/dist/stores/plugins/serviceContainer.js +14 -0
  190. package/dist/stores/sessionStore.d.ts +71 -0
  191. package/dist/stores/sessionStore.d.ts.map +1 -0
  192. package/dist/stores/sessionStore.js +125 -0
  193. package/dist/types/app.types.d.ts +202 -0
  194. package/dist/types/app.types.d.ts.map +1 -0
  195. package/dist/types/app.types.js +6 -0
  196. package/dist/types/config.types.d.ts +2 -0
  197. package/dist/types/config.types.d.ts.map +1 -0
  198. package/dist/types/config.types.js +1 -0
  199. package/dist/types/global.d.ts +33 -0
  200. package/dist/types/i18n.types.d.ts +21 -0
  201. package/dist/types/i18n.types.d.ts.map +1 -0
  202. package/dist/types/i18n.types.js +6 -0
  203. package/dist/types/laravel.types.d.ts +167 -0
  204. package/dist/types/laravel.types.d.ts.map +1 -0
  205. package/dist/types/laravel.types.js +6 -0
  206. package/dist/types/logging.types.d.ts +81 -0
  207. package/dist/types/logging.types.d.ts.map +1 -0
  208. package/dist/types/logging.types.js +22 -0
  209. package/dist/types/pinia.d.ts +24 -0
  210. package/dist/types/scripts.types.d.ts +31 -0
  211. package/dist/types/scripts.types.d.ts.map +1 -0
  212. package/dist/types/scripts.types.js +6 -0
  213. package/dist/types/ssr.d.ts +11 -0
  214. package/dist/types/task.types.d.ts +121 -0
  215. package/dist/types/task.types.d.ts.map +1 -0
  216. package/dist/types/task.types.js +7 -0
  217. package/dist/types/theme.types.d.ts +13 -0
  218. package/dist/types/theme.types.d.ts.map +1 -0
  219. package/dist/types/theme.types.js +17 -0
  220. package/dist/types/user.types.d.ts +24 -0
  221. package/dist/types/user.types.d.ts.map +1 -0
  222. package/dist/types/user.types.js +1 -0
  223. package/dist/types/vue-shim.d.ts +11 -0
  224. package/dist/types/websocket.types.d.ts +62 -0
  225. package/dist/types/websocket.types.d.ts.map +1 -0
  226. package/dist/types/websocket.types.js +6 -0
  227. package/dist/utils/apiInterceptors.d.ts +76 -0
  228. package/dist/utils/apiInterceptors.d.ts.map +1 -0
  229. package/dist/utils/apiInterceptors.js +149 -0
  230. package/dist/utils/assets.d.ts +40 -0
  231. package/dist/utils/assets.d.ts.map +1 -0
  232. package/dist/utils/assets.js +340 -0
  233. package/dist/utils/axios.d.ts +19 -0
  234. package/dist/utils/axios.d.ts.map +1 -0
  235. package/dist/utils/axios.js +113 -0
  236. package/dist/utils/config.d.ts +16 -0
  237. package/dist/utils/config.d.ts.map +1 -0
  238. package/dist/utils/config.js +48 -0
  239. package/dist/utils/container.d.ts +12 -0
  240. package/dist/utils/container.d.ts.map +1 -0
  241. package/dist/utils/container.js +11 -0
  242. package/dist/utils/deepMerge.d.ts +28 -0
  243. package/dist/utils/deepMerge.d.ts.map +1 -0
  244. package/dist/utils/deepMerge.js +59 -0
  245. package/dist/utils/envConfig.d.ts +73 -0
  246. package/dist/utils/envConfig.d.ts.map +1 -0
  247. package/dist/utils/envConfig.js +161 -0
  248. package/dist/utils/error.d.ts +44 -0
  249. package/dist/utils/error.d.ts.map +1 -0
  250. package/dist/utils/error.js +67 -0
  251. package/dist/utils/headers.d.ts +36 -0
  252. package/dist/utils/headers.d.ts.map +1 -0
  253. package/dist/utils/headers.js +54 -0
  254. package/dist/utils/i18n.d.ts +26 -0
  255. package/dist/utils/i18n.d.ts.map +1 -0
  256. package/dist/utils/i18n.js +56 -0
  257. package/dist/utils/index.d.ts +14 -0
  258. package/dist/utils/index.d.ts.map +1 -0
  259. package/dist/utils/index.js +13 -0
  260. package/dist/utils/loading.d.ts +29 -0
  261. package/dist/utils/loading.d.ts.map +1 -0
  262. package/dist/utils/loading.js +46 -0
  263. package/dist/utils/logging.d.ts +20 -0
  264. package/dist/utils/logging.d.ts.map +1 -0
  265. package/dist/utils/logging.js +54 -0
  266. package/dist/utils/notify.d.ts +15 -0
  267. package/dist/utils/notify.d.ts.map +1 -0
  268. package/dist/utils/notify.js +30 -0
  269. package/dist/utils/object.d.ts +28 -0
  270. package/dist/utils/object.d.ts.map +1 -0
  271. package/dist/utils/object.js +48 -0
  272. package/dist/utils/pagination.d.ts +60 -0
  273. package/dist/utils/pagination.d.ts.map +1 -0
  274. package/dist/utils/pagination.js +252 -0
  275. package/dist/utils/paths.d.ts +54 -0
  276. package/dist/utils/paths.d.ts.map +1 -0
  277. package/dist/utils/paths.js +48 -0
  278. package/dist/utils/platform.d.ts +25 -0
  279. package/dist/utils/platform.d.ts.map +1 -0
  280. package/dist/utils/platform.js +64 -0
  281. package/dist/utils/scripts.d.ts +20 -0
  282. package/dist/utils/scripts.d.ts.map +1 -0
  283. package/dist/utils/scripts.js +39 -0
  284. package/global.d.ts +29 -0
  285. package/package.json +119 -0
package/README.md ADDED
@@ -0,0 +1,670 @@
1
+ # @quvel-kit/core
2
+
3
+ Core utilities and infrastructure for Quasar + Laravel applications.
4
+
5
+ ## Features
6
+
7
+ ### Service Container System
8
+ - **Isomorphic per-request container** with Initialize → Boot → Register lifecycle
9
+ - **SSR-aware services** that can boot with request context
10
+ - **Dependency injection** with type-safe service resolution
11
+ - **Service registration** and lifecycle management
12
+
13
+ ### Core Services
14
+
15
+ All services are included and ready to use out of the box:
16
+ - **LogService** - Structured logging with trace correlation
17
+ - **ApiService** - Axios-based HTTP client with automatic trace headers
18
+ - **I18nService** - Internationalization with module support
19
+ - **ValidationService** - Zod-based validation with i18n integration
20
+ - **WebSocketService** - Laravel Echo + Pusher WebSocket support
21
+ - **TaskService** - Async task management with loading/error handling
22
+ - **ThemeService** - Light/dark mode management
23
+
24
+ **Configuration** is managed directly by the ServiceContainer as a first-class property, not as a service. All services receive `AppConfig` in their constructor.
25
+
26
+ ### Module System
27
+ - Module-based architecture for routes, i18n, services, and build config
28
+ - Resource path helpers for module assets
29
+ - Dynamic service registration per module
30
+
31
+ ### Utilities
32
+ - **Asset loading** - Dynamic CSS/JS injection for client and SSR
33
+ - **Theme management** - Light/dark mode with Quasar and Tailwind
34
+ - **Script loading** - Dynamic external script management
35
+ - **Error handling** - Laravel validation error processing
36
+ - **Config utilities** - Environment-based configuration merging
37
+
38
+ ### Composables
39
+ - **useQuvel** - Access Quvel service container in components
40
+ - **useClient** - Client-side detection for SSR-aware components
41
+ - **useWindowEvent** - Safe window event listener management
42
+ - **useScript** - Dynamic script loading with state tracking
43
+ - **useMetaConfig** - Page meta tags with SEO optimization
44
+ - **useWebSockets** - WebSocket channel subscription
45
+ - **useScopedService** - Component-scoped service instances
46
+ - **useRecaptcha** - Google reCAPTCHA integration
47
+ - **useXsrf** - XSRF token management
48
+ - **useQueryMessageHandler** - URL query parameter message handling
49
+ - **useUrlQueryHandler** - Generic URL query parameter processing
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ npm install @quvel-kit/core
55
+ # or
56
+ yarn add @quvel-kit/core
57
+ ```
58
+
59
+ ## Configuration
60
+
61
+ ### Environment Variables
62
+
63
+ See [.env.example](./.env.example) for all available configuration options.
64
+
65
+ #### Required Variables
66
+
67
+ ```bash
68
+ # Application name
69
+ VITE_APP_NAME="My App"
70
+
71
+ # Backend API URL (Laravel)
72
+ VITE_API_URL=http://localhost:8000
73
+
74
+ # Frontend app URL (Quasar)
75
+ VITE_APP_URL=http://localhost:9000
76
+ ```
77
+
78
+ #### Optional Variables
79
+
80
+ ```bash
81
+ # Application environment
82
+ VITE_APP_ENV=local
83
+
84
+ # Debug mode
85
+ VITE_DEBUG=true
86
+
87
+ # Application timezone
88
+ VITE_TIMEZONE=UTC
89
+
90
+ # Application locale
91
+ VITE_LOCALE=en
92
+
93
+ # Fallback locale
94
+ VITE_FALLBACK_LOCALE=en
95
+
96
+ # Session cookie name (must match Laravel)
97
+ VITE_SESSION_NAME=quvel_session
98
+
99
+ # Internal API URL for SSR server to backend communication
100
+ # Can be an internal network address for better performance
101
+ # Defaults to VITE_API_URL if not set
102
+ VITE_INTERNAL_API_URL=http://api-internal:8000
103
+
104
+ # Capacitor custom scheme for mobile apps
105
+ VITE_CAPACITOR_SCHEME=myapp
106
+ ```
107
+
108
+ ### AppConfig Structure
109
+
110
+ The configuration follows a structured format matching the backend:
111
+
112
+ ```typescript
113
+ interface AppConfig {
114
+ app: {
115
+ name: string; // Application name
116
+ url: string; // Backend API URL
117
+ env?: string; // Environment (local, development, production)
118
+ debug?: boolean; // Debug mode
119
+ timezone?: string; // Timezone (UTC, America/New_York, etc.)
120
+ locale?: string; // Default locale (en, es, fr, etc.)
121
+ fallback_locale?: string; // Fallback locale
122
+ };
123
+ frontend: {
124
+ url: string; // Frontend app URL
125
+ custom_scheme?: string; // Capacitor custom scheme
126
+ };
127
+ assets?: AppAssets; // Dynamic CSS/JS injection
128
+ meta?: AppMeta; // Page meta configuration
129
+ headers?: HeadersConfig; // HTTP headers customization
130
+ api?: AppApiConfig; // API configuration (SSR key, etc.)
131
+ broadcasting?: BroadcastingConfig; // WebSocket/Pusher configuration
132
+ session?: SessionConfig; // Session cookie configuration
133
+ i18nCookie?: string; // I18n locale cookie name
134
+ userFactory?: UserFactory; // Custom user model factory
135
+ trace?: TraceInfo; // Request trace context (SSR-injected)
136
+ [key: string]: any; // Extensible for custom config
137
+ }
138
+ ```
139
+
140
+ **Note:** The `VITE_INTERNAL_API_URL` environment variable is used internally by `@quvel-kit/ssr`'s SSRApiService and is not part of the `AppConfig` structure exposed to your application. It configures how the SSR server communicates with the backend.
141
+
142
+ ## Usage
143
+
144
+ ### Service Container
145
+
146
+ ```typescript
147
+ import { createContainer, LogService } from '@quvel-kit/core';
148
+
149
+ // Create container with services
150
+ const container = createContainer(
151
+ undefined, // SSR context (optional)
152
+ new Map([
153
+ ['LogService', LogService],
154
+ ])
155
+ );
156
+
157
+ // Access config (managed by container)
158
+ const config = container.config;
159
+
160
+ // Access services
161
+ const log = container.get(LogService);
162
+ ```
163
+
164
+ ### Using Services in Components
165
+
166
+ ```typescript
167
+ import { useQuvel } from '@quvel-kit/core';
168
+
169
+ export default defineComponent({
170
+ setup() {
171
+ const { config, log, api, i18n, task } = useQuvel();
172
+
173
+ const fetchData = async () => {
174
+ const data = await api.get('/users');
175
+ log.info('Fetched users', { count: data.length });
176
+ return data;
177
+ };
178
+
179
+ return { fetchData };
180
+ }
181
+ });
182
+ ```
183
+
184
+ ### TaskService Example
185
+
186
+ ```typescript
187
+ import { useQuvel } from '@quvel-kit/core';
188
+
189
+ export default defineComponent({
190
+ setup() {
191
+ const { task, api } = useQuvel();
192
+
193
+ const loginTask = task({
194
+ task: (credentials) => api.post('/login', credentials),
195
+ showLoading: true,
196
+ showNotification: {
197
+ success: 'Login successful!',
198
+ error: true, // Use default error message
199
+ },
200
+ handleLaravelError: true, // Auto-handle Laravel validation errors
201
+ });
202
+
203
+ const login = async () => {
204
+ const result = await loginTask.run();
205
+ if (result) {
206
+ router.push('/dashboard');
207
+ }
208
+ };
209
+
210
+ return { login, loginTask };
211
+ }
212
+ });
213
+ ```
214
+
215
+ ### Optional API Debug Interceptors
216
+
217
+ The core package provides optional debugging interceptors that can be enabled in development. Create a boot file to enable them:
218
+
219
+ ```typescript
220
+ // src/boot/api-debug.ts
221
+ import { boot } from 'quasar/wrappers';
222
+ import { useQuvel } from '@quvel-kit/core';
223
+ import { createDebugInterceptors } from '@quvel-kit/core/utils';
224
+
225
+ export default boot(({ ssrContext }) => {
226
+ if (import.meta.env.VITE_AXIOS_INTERCEPTORS === 'true') {
227
+ const quvel = useQuvel();
228
+ const interceptors = createDebugInterceptors(quvel.log, quvel.config, {
229
+ onRequest: (config) => {
230
+ // Custom request logging
231
+ },
232
+ onResponse: (response) => {
233
+ // Custom response logging
234
+ }
235
+ });
236
+
237
+ quvel.api.instance.interceptors.request.use(
238
+ interceptors.request.onFulfilled,
239
+ interceptors.request.onRejected
240
+ );
241
+
242
+ quvel.api.instance.interceptors.response.use(
243
+ interceptors.response.onFulfilled,
244
+ interceptors.response.onRejected
245
+ );
246
+ }
247
+ });
248
+ ```
249
+
250
+ Enable in `.env`:
251
+ ```bash
252
+ VITE_AXIOS_INTERCEPTORS=true
253
+ ```
254
+
255
+ ### Dynamic Asset Loading
256
+
257
+ ```typescript
258
+ import { injectAssets } from '@quvel-kit/core';
259
+
260
+ // Client-side dynamic asset injection
261
+ injectAssets({
262
+ css: [
263
+ {
264
+ url: 'https://cdn.example.com/styles.css',
265
+ priority: 'critical',
266
+ position: 'head',
267
+ }
268
+ ],
269
+ js: [
270
+ {
271
+ url: 'https://cdn.example.com/script.js',
272
+ loading: 'deferred',
273
+ position: 'body-end',
274
+ }
275
+ ]
276
+ });
277
+ ```
278
+
279
+ ### Theme Management
280
+
281
+ ```typescript
282
+ import { useQuvel } from '@quvel-kit/core';
283
+
284
+ export default defineComponent({
285
+ setup() {
286
+ const { theme } = useQuvel();
287
+
288
+ // Get current theme
289
+ const currentTheme = theme.theme; // 'light' | 'dark'
290
+
291
+ // Set specific theme
292
+ theme.setTheme('dark');
293
+
294
+ // Toggle between light and dark
295
+ theme.toggleTheme();
296
+
297
+ return { currentTheme };
298
+ }
299
+ });
300
+ ```
301
+
302
+ Theme is automatically loaded from cookies or system preference during SSR boot. The ThemeService manages Quasar Dark mode and Tailwind classes.
303
+
304
+ ### I18n with Modules
305
+
306
+ ```typescript
307
+ import { I18nService } from '@quvel-kit/core';
308
+ import { getTranslations } from '@quvel-kit/core';
309
+ import { modules } from './modules';
310
+
311
+ // Aggregate translations from modules
312
+ const messages = {
313
+ 'en-US': getTranslations(modules, 'en-US'),
314
+ 'es-ES': getTranslations(modules, 'es-ES')
315
+ };
316
+
317
+ // Set translations before booting container
318
+ I18nService.setTranslations(messages);
319
+
320
+ // In component
321
+ const { i18n } = useQuvel();
322
+ i18n.t('common.welcome'); // Access translations
323
+ ```
324
+
325
+ ### WebSocket Subscriptions
326
+
327
+ ```typescript
328
+ import { useWebSockets } from '@quvel-kit/core';
329
+
330
+ export default defineComponent({
331
+ setup() {
332
+ const { subscribe, unsubscribe } = useWebSockets();
333
+
334
+ onMounted(async () => {
335
+ const channel = await subscribe({
336
+ type: 'private',
337
+ channelName: 'user.1',
338
+ events: {
339
+ 'notification': (data) => {
340
+ console.log('Notification received:', data);
341
+ }
342
+ }
343
+ });
344
+
345
+ onBeforeUnmount(() => {
346
+ unsubscribe(channel);
347
+ });
348
+ });
349
+ }
350
+ });
351
+ ```
352
+
353
+ ## Module System
354
+
355
+ The module system organizes features into self-contained units. Each module contributes routes, services, translations, and build configuration. Modules compose into applications without tight coupling.
356
+
357
+ ### Module Structure
358
+
359
+ A module is a plain object with optional properties:
360
+
361
+ ```typescript
362
+ export interface Module {
363
+ routes?: RouteRecordRaw[]; // Vue Router routes
364
+ services?: ServiceRegistry; // Service classes for DI
365
+ i18n?: TranslationRegistry; // Translations by locale
366
+ build?: ModuleBuildConfig; // Build-time configuration
367
+ }
368
+ ```
369
+
370
+ All properties are optional. Modules implement only what they need.
371
+
372
+ ### Creating a Module
373
+
374
+ Define a module by exporting an object:
375
+
376
+ ```typescript
377
+ // modules/Auth/index.ts
378
+ import type { Module } from '@quvel-kit/core';
379
+ import { AuthService } from './services/AuthService';
380
+
381
+ export const AuthModule: Module = {
382
+ routes: [
383
+ {
384
+ path: '/login',
385
+ component: () => import('./pages/LoginPage.vue')
386
+ },
387
+ {
388
+ path: '/register',
389
+ component: () => import('./pages/RegisterPage.vue')
390
+ }
391
+ ],
392
+
393
+ services: {
394
+ AuthService: AuthService
395
+ },
396
+
397
+ i18n: {
398
+ 'en-US': {
399
+ auth: {
400
+ login: 'Login',
401
+ register: 'Register',
402
+ logout: 'Logout'
403
+ }
404
+ },
405
+ 'es-ES': {
406
+ auth: {
407
+ login: 'Iniciar sesión',
408
+ register: 'Registrarse',
409
+ logout: 'Cerrar sesión'
410
+ }
411
+ }
412
+ },
413
+
414
+ build: {
415
+ boot: ['auth'],
416
+ css: ['auth.css'],
417
+ plugins: ['Notify']
418
+ }
419
+ };
420
+ ```
421
+
422
+ ### Registering Modules
423
+
424
+ Collect modules in a registry:
425
+
426
+ ```typescript
427
+ // src/modules/index.ts
428
+ import { AuthModule } from './Auth';
429
+ import { DashboardModule } from './Dashboard';
430
+ import { ProfileModule } from './Profile';
431
+
432
+ export const modules = {
433
+ Auth: AuthModule,
434
+ Dashboard: DashboardModule,
435
+ Profile: ProfileModule
436
+ };
437
+ ```
438
+
439
+ ### Router Integration
440
+
441
+ Aggregate routes from all modules:
442
+
443
+ ```typescript
444
+ // src/router/routes.ts
445
+ import { getRoutes } from '@quvel-kit/core';
446
+ import { modules } from '../modules';
447
+
448
+ const routes = [
449
+ {
450
+ path: '/',
451
+ component: () => import('layouts/MainLayout.vue'),
452
+ children: getRoutes(modules) // Inject module routes
453
+ }
454
+ ];
455
+
456
+ export default routes;
457
+ ```
458
+
459
+ ### Service Container Integration
460
+
461
+ Register services from modules:
462
+
463
+ ```typescript
464
+ // src/boot/quvel.ts
465
+ import { defineQuvelBoot, getServices } from '@quvel-kit/core';
466
+ import { modules } from '../modules';
467
+
468
+ export default defineQuvelBoot(getServices(modules));
469
+ ```
470
+
471
+ ### I18n Integration
472
+
473
+ Load translations from modules:
474
+
475
+ ```typescript
476
+ // src/i18n/index.ts
477
+ import { getTranslations } from '@quvel-kit/core';
478
+ import { modules } from '../modules';
479
+
480
+ export default {
481
+ messages: {
482
+ 'en-US': getTranslations(modules, 'en-US'),
483
+ 'es-ES': getTranslations(modules, 'es-ES')
484
+ }
485
+ };
486
+ ```
487
+
488
+ ### Build Configuration
489
+
490
+ Apply module build configs in Quasar config:
491
+
492
+ ```typescript
493
+ // quasar.config.ts
494
+ import { createModuleTransformer } from '@quvel-kit/core/config/moduleTransformer';
495
+ import { modules } from './src/modules';
496
+
497
+ export default configure((ctx) => {
498
+ let config = {
499
+ boot: [],
500
+ css: [],
501
+ framework: {
502
+ plugins: []
503
+ }
504
+ };
505
+
506
+ // Apply module configs
507
+ config = createModuleTransformer(modules)(config, ctx);
508
+
509
+ return config;
510
+ });
511
+ ```
512
+
513
+ The transformer merges all module build configs into Quasar's configuration automatically.
514
+
515
+ ### Module Build Config
516
+
517
+ Modules declare build-time resources:
518
+
519
+ ```typescript
520
+ build: {
521
+ boot: ['auth', 'permissions'], // Boot files to load
522
+ css: ['module.css', 'theme.scss'], // CSS files to include
523
+ animations: ['fadeIn', 'slideUp'], // Quasar animations
524
+ plugins: ['Notify', 'Dialog'] // Quasar plugins
525
+ }
526
+ ```
527
+
528
+ Boot files support client/server targeting:
529
+
530
+ ```typescript
531
+ build: {
532
+ boot: [
533
+ { path: 'auth', server: true, client: true },
534
+ { path: 'analytics', server: false, client: true }
535
+ ]
536
+ }
537
+ ```
538
+
539
+ ### Why Modules?
540
+
541
+ **Without modules:**
542
+ - Routes scattered across files
543
+ - Services manually wired together
544
+ - Translations duplicated
545
+ - Build config becomes unwieldy
546
+
547
+ **With modules:**
548
+ - Features are self-contained
549
+ - Adding a module is one line
550
+ - Removing a module is one line
551
+ - Zero manual wiring
552
+
553
+ ## Architecture
554
+
555
+ ### Service Lifecycle
556
+
557
+ Core uses a three-phase service lifecycle for dependency injection:
558
+
559
+ 1. **Initialize** - Service classes are instantiated with `config` and `ssrContext`
560
+ 2. **Register** - Services receive the container and store references to dependencies
561
+ 3. **Boot** - Services use their dependencies for initialization (SSR-aware services only)
562
+
563
+ **Important:** Config is passed to all services in their constructor, so it's always available. Services like `LogService` and `I18nService` self-initialize in their constructors. Other services that initialize during `register()` may not be ready yet when accessed by other services during their `register()` phase.
564
+
565
+ All services complete their `register()` phase before any `boot()` phase begins. The `boot()` phase is where you can safely use ALL dependencies without ordering concerns.
566
+
567
+ #### Service Constructor Signature
568
+
569
+ Services receive config first, then ssrContext:
570
+
571
+ ```typescript
572
+ import type { QSsrContext } from '@quasar/app-vite';
573
+ import type { AppConfig } from '@quvel-kit/core';
574
+ import { Service } from '@quvel-kit/core';
575
+
576
+ export class MyService extends Service {
577
+ private readonly config: AppConfig;
578
+
579
+ constructor(config: AppConfig, ssrContext?: QSsrContext | null) {
580
+ super(config, ssrContext);
581
+ this.config = config;
582
+ // Config is always available in constructor
583
+ }
584
+ }
585
+ ```
586
+
587
+ #### Register Method Signature
588
+
589
+ Use destructuring in your `register()` method for clean dependency access:
590
+
591
+ ```typescript
592
+ import type { ServiceContainer } from '@quvel-kit/core';
593
+ import type { RegisterService } from '@quvel-kit/core';
594
+
595
+ export class MyService extends Service implements RegisterService {
596
+ private api!: ApiService;
597
+
598
+ // Use destructuring to access dependencies
599
+ register({ api, config, ssrContext }: ServiceContainer): void {
600
+ this.api = api;
601
+ // config and ssrContext are also available from container
602
+ this.client = createClient(ssrContext, config);
603
+ }
604
+ }
605
+ ```
606
+
607
+ #### Safety Guidelines
608
+
609
+ ```typescript
610
+ // ✅ ALWAYS SAFE: Config is passed in constructor
611
+ constructor(config: AppConfig, ssrContext?: QSsrContext | null) {
612
+ super(config, ssrContext);
613
+ this.config = config; // ✓ Always available
614
+ const debug = this.config.app.debug; // ✓ Safe to use
615
+ }
616
+
617
+ // ✅ ALWAYS SAFE: Config and Log via container
618
+ register({ config, log }: ServiceContainer): void {
619
+ const debug = config.app.debug; // ✓ Always ready
620
+ log.info('Service registered'); // ✓ Safe to use
621
+ }
622
+
623
+ // ⚠️ ORDERING ISSUE: Using services that initialize during register()
624
+ register({ i18n }: ServiceContainer): void {
625
+ this.i18n = i18n;
626
+ // This may fail if your service registers before I18nService!
627
+ const message = this.i18n.t('key'); // Race condition based on order
628
+ }
629
+
630
+ // ✅ CORRECT: Use all dependencies in boot()
631
+ boot(): void {
632
+ // All services are fully initialized - safe to use anything
633
+ const locale = this.config.app.locale;
634
+ const message = this.i18n.t('welcome');
635
+ this.api.setHeader('locale', locale);
636
+ }
637
+ ```
638
+
639
+ ### SSR Support
640
+
641
+ Services can be SSR-aware by implementing the `SsrAwareService` interface:
642
+
643
+ ```typescript
644
+ import type { QSsrContext } from '@quasar/app-vite';
645
+
646
+ export class MyService extends Service implements SsrAwareService {
647
+ boot(ssrContext?: QSsrContext | null): void {
648
+ // Access Quasar instance for SSR
649
+ if (ssrContext?.$q) {
650
+ ssrContext.$q.dark.set(true);
651
+ }
652
+
653
+ // Access request context
654
+ const config = ssrContext?.req?.requestContext?.appConfig;
655
+ }
656
+ }
657
+ ```
658
+
659
+ ## TypeScript Support
660
+
661
+ Full TypeScript support with comprehensive type definitions for:
662
+ - Service container and dependency injection
663
+ - Configuration structures
664
+ - API request/response types
665
+ - WebSocket channel types
666
+ - Task options and handlers
667
+
668
+ ## License
669
+
670
+ MIT
@@ -0,0 +1,54 @@
1
+ import type { Router } from 'vue-router';
2
+ import type { AuthGuardConfig } from '../services/AuthGuard.js';
3
+ /**
4
+ * Configuration for auth guard boot
5
+ */
6
+ export interface DefineAuthGuardConfig extends AuthGuardConfig {
7
+ /**
8
+ * Function to check if a user is authenticated
9
+ * Should return the current authentication state
10
+ */
11
+ isAuthenticated: () => boolean;
12
+ /**
13
+ * Function to ensure the session is initialized
14
+ * Called before auth checks to load session if needed
15
+ */
16
+ ensureSessionInitialized: () => Promise<void>;
17
+ }
18
+ /**
19
+ * Create auth guard boot function
20
+ *
21
+ * This helper creates a Quasar boot function that sets up authentication
22
+ * guards for the router using the framework-agnostic AuthGuard service.
23
+ *
24
+ * @param config - Auth guard configuration
25
+ * @returns Boot function for Quasar
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import { defineAuthGuard } from '@quvel-kit/core/auth';
30
+ * import { useSessionStore } from '../stores/sessionStore';
31
+ *
32
+ * export default boot(defineAuthGuard({
33
+ * requireAuthByDefault: true,
34
+ * loginRoute: 'login',
35
+ * successRoute: 'dashboard',
36
+ * isAuthenticated: () => useSessionStore().isAuthenticated,
37
+ * ensureSessionInitialized: async () => {
38
+ * const store = useSessionStore();
39
+ * if (!store.isInitialized) {
40
+ * await store.fetchSession();
41
+ * }
42
+ * },
43
+ * }));
44
+ * ```
45
+ */
46
+ export declare function defineAuthGuard(config: DefineAuthGuardConfig): ({ router, urlPath, redirect }: {
47
+ router: Router;
48
+ urlPath: string;
49
+ redirect: (opts: {
50
+ name?: string;
51
+ path?: string;
52
+ }) => void;
53
+ }) => Promise<void>;
54
+ //# sourceMappingURL=defineAuthGuard.d.ts.map