@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
@@ -0,0 +1,340 @@
1
+ /**
2
+ * Asset Loading Utilities
3
+ *
4
+ * Helper functions for dynamically loading CSS and JS assets
5
+ * Support both client-side and SSR asset injection
6
+ */
7
+ /**
8
+ * Validates if a URL is safe to load as an asset
9
+ * Prevents loading from potentially malicious sources
10
+ */
11
+ export function isValidAssetUrl(url) {
12
+ try {
13
+ // Allow relative URLs
14
+ if (url.startsWith('/')) {
15
+ return true;
16
+ }
17
+ const parsedUrl = new URL(url);
18
+ // Only allow HTTPS in production
19
+ if (import.meta.env.MODE === 'production' && parsedUrl.protocol !== 'https:') {
20
+ return false;
21
+ }
22
+ // Allow HTTP/HTTPS
23
+ if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
24
+ return false;
25
+ }
26
+ return true;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * Sanitizes inline content to prevent XSS attacks
34
+ * Basic implementation - consider using DOMPurify for more robust protection
35
+ */
36
+ export function sanitizeInlineContent(content) {
37
+ // Remove script tags and event handlers
38
+ return content
39
+ .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
40
+ .replace(/on\w+\s*=\s*"[^"]*"/gi, '')
41
+ .replace(/on\w+\s*=\s*'[^']*'/gi, '')
42
+ .replace(/javascript:/gi, '');
43
+ }
44
+ /**
45
+ * Creates a CSS link or style element from configuration
46
+ */
47
+ export function createCSSElement(config) {
48
+ if (config.url) {
49
+ if (!isValidAssetUrl(config.url)) {
50
+ console.warn('Invalid CSS URL:', config.url);
51
+ return null;
52
+ }
53
+ const link = document.createElement('link');
54
+ link.rel = 'stylesheet';
55
+ link.href = config.url;
56
+ if (config.media) {
57
+ link.media = config.media;
58
+ }
59
+ if (config.integrity) {
60
+ link.integrity = config.integrity;
61
+ }
62
+ if (config.crossorigin) {
63
+ link.crossOrigin = config.crossorigin;
64
+ }
65
+ // Handle loading priority for CSS
66
+ if (config.priority === 'critical') {
67
+ link.rel = 'preload';
68
+ link.as = 'style';
69
+ link.onload = () => {
70
+ link.rel = 'stylesheet';
71
+ };
72
+ }
73
+ else if (config.priority === 'low') {
74
+ link.media = 'print';
75
+ link.onload = () => {
76
+ link.media = config.media || 'all';
77
+ };
78
+ }
79
+ return link;
80
+ }
81
+ else if (config.inline) {
82
+ const style = document.createElement('style');
83
+ style.textContent = sanitizeInlineContent(config.inline);
84
+ if (config.priority) {
85
+ style.setAttribute('data-priority', config.priority);
86
+ }
87
+ return style;
88
+ }
89
+ return null;
90
+ }
91
+ /**
92
+ * Creates a JavaScript script element from configuration
93
+ */
94
+ export function createJSElement(config) {
95
+ const script = document.createElement('script');
96
+ if (config.url) {
97
+ if (!isValidAssetUrl(config.url)) {
98
+ console.warn('Invalid JS URL:', config.url);
99
+ return null;
100
+ }
101
+ script.src = config.url;
102
+ if (config.integrity) {
103
+ script.integrity = config.integrity;
104
+ }
105
+ if (config.crossorigin) {
106
+ script.crossOrigin = config.crossorigin;
107
+ }
108
+ }
109
+ else if (config.inline) {
110
+ script.textContent = sanitizeInlineContent(config.inline);
111
+ }
112
+ else {
113
+ return null;
114
+ }
115
+ if (config.loading === 'immediate') {
116
+ // No defer/async - loads and executes immediately
117
+ }
118
+ else if (config.loading === 'deferred') {
119
+ script.defer = true;
120
+ }
121
+ else if (config.loading === 'lazy') {
122
+ script.async = true;
123
+ }
124
+ else {
125
+ if (config.defer) {
126
+ script.defer = true;
127
+ }
128
+ if (config.async) {
129
+ script.async = true;
130
+ }
131
+ }
132
+ if (config.priority) {
133
+ script.setAttribute('data-priority', config.priority);
134
+ }
135
+ if (config.position) {
136
+ script.setAttribute('data-position', config.position);
137
+ }
138
+ return script;
139
+ }
140
+ /**
141
+ * Injects an element at the specified position in the document
142
+ */
143
+ function injectElementAtPosition(element, position) {
144
+ switch (position) {
145
+ case 'head':
146
+ document.head.appendChild(element);
147
+ break;
148
+ case 'body-start':
149
+ if (document.body.firstChild) {
150
+ document.body.insertBefore(element, document.body.firstChild);
151
+ }
152
+ else {
153
+ document.body.appendChild(element);
154
+ }
155
+ break;
156
+ case 'body-end':
157
+ default:
158
+ document.body.appendChild(element);
159
+ break;
160
+ }
161
+ }
162
+ /**
163
+ * Injects app assets into the document
164
+ * Used by client-side asset loading (non-SSR modes)
165
+ */
166
+ export function injectAssets(assets) {
167
+ if (!assets)
168
+ return;
169
+ // Sort and inject CSS assets by priority
170
+ if (assets.css?.length) {
171
+ const sortedCSS = [...assets.css].sort((a, b) => {
172
+ const priorityOrder = { critical: 0, normal: 1, low: 2 };
173
+ const aPriority = priorityOrder[a.priority || 'normal'];
174
+ const bPriority = priorityOrder[b.priority || 'normal'];
175
+ return aPriority - bPriority;
176
+ });
177
+ sortedCSS.forEach((cssConfig) => {
178
+ const element = createCSSElement(cssConfig);
179
+ if (element) {
180
+ const position = cssConfig.position || 'head';
181
+ injectElementAtPosition(element, position);
182
+ }
183
+ });
184
+ }
185
+ if (assets.js?.length) {
186
+ const sortedJS = [...assets.js].sort((a, b) => {
187
+ const priorityOrder = { critical: 0, normal: 1, low: 2 };
188
+ const loadingOrder = { immediate: 0, deferred: 1, lazy: 2 };
189
+ const aPriority = priorityOrder[a.priority || 'normal'];
190
+ const bPriority = priorityOrder[b.priority || 'normal'];
191
+ if (aPriority !== bPriority)
192
+ return aPriority - bPriority;
193
+ const aLoading = loadingOrder[a.loading || 'deferred'];
194
+ const bLoading = loadingOrder[b.loading || 'deferred'];
195
+ return aLoading - bLoading;
196
+ });
197
+ const immediateScripts = sortedJS.filter((js) => js.loading === 'immediate');
198
+ const deferredScripts = sortedJS.filter((js) => js.loading !== 'immediate');
199
+ immediateScripts.forEach((jsConfig) => {
200
+ const element = createJSElement(jsConfig);
201
+ if (element) {
202
+ const position = jsConfig.position || 'head';
203
+ injectElementAtPosition(element, position);
204
+ }
205
+ });
206
+ if (deferredScripts.length > 0) {
207
+ const processDeferred = () => {
208
+ deferredScripts.forEach((jsConfig) => {
209
+ const element = createJSElement(jsConfig);
210
+ if (element) {
211
+ const position = jsConfig.position || 'body-end';
212
+ injectElementAtPosition(element, position);
213
+ }
214
+ });
215
+ };
216
+ if ('requestIdleCallback' in window) {
217
+ requestIdleCallback(processDeferred);
218
+ }
219
+ else {
220
+ setTimeout(processDeferred, 0);
221
+ }
222
+ }
223
+ }
224
+ }
225
+ /**
226
+ * Generates HTML strings for server-side asset injection
227
+ * Used by SSR asset injection
228
+ */
229
+ export function generateAssetHTML(assets) {
230
+ let headHTML = '';
231
+ let bodyStartHTML = '';
232
+ let bodyEndHTML = '';
233
+ if (!assets) {
234
+ return { headHTML, bodyStartHTML, bodyEndHTML };
235
+ }
236
+ const sortedCSS = assets.css
237
+ ? [...assets.css].sort((a, b) => {
238
+ const priorityOrder = { critical: 0, normal: 1, low: 2 };
239
+ const aPriority = priorityOrder[a.priority || 'normal'];
240
+ const bPriority = priorityOrder[b.priority || 'normal'];
241
+ return aPriority - bPriority;
242
+ })
243
+ : [];
244
+ const sortedJS = assets.js
245
+ ? [...assets.js].sort((a, b) => {
246
+ const priorityOrder = { critical: 0, normal: 1, low: 2 };
247
+ const loadingOrder = { immediate: 0, deferred: 1, lazy: 2 };
248
+ const aPriority = priorityOrder[a.priority || 'normal'];
249
+ const bPriority = priorityOrder[b.priority || 'normal'];
250
+ if (aPriority !== bPriority)
251
+ return aPriority - bPriority;
252
+ const aLoading = loadingOrder[a.loading || 'deferred'];
253
+ const bLoading = loadingOrder[b.loading || 'deferred'];
254
+ return aLoading - bLoading;
255
+ })
256
+ : [];
257
+ sortedCSS.forEach((config) => {
258
+ let cssHTML = '';
259
+ if (config.url && isValidAssetUrl(config.url)) {
260
+ const attrs = [];
261
+ if (config.media)
262
+ attrs.push(`media="${config.media}"`);
263
+ if (config.integrity)
264
+ attrs.push(`integrity="${config.integrity}"`);
265
+ if (config.crossorigin)
266
+ attrs.push(`crossorigin="${config.crossorigin}"`);
267
+ if (config.priority)
268
+ attrs.push(`data-priority="${config.priority}"`);
269
+ if (config.priority === 'critical') {
270
+ cssHTML = `<link rel="preload" href="${config.url}" as="style" onload="this.rel='stylesheet'" ${attrs.join(' ')}>`;
271
+ }
272
+ else if (config.priority === 'low') {
273
+ cssHTML = `<link rel="stylesheet" href="${config.url}" media="print" onload="this.media='${config.media || 'all'}'" ${attrs.join(' ')}>`;
274
+ }
275
+ else {
276
+ cssHTML = `<link rel="stylesheet" href="${config.url}" ${attrs.join(' ')}>`;
277
+ }
278
+ }
279
+ else if (config.inline) {
280
+ const priorityAttr = config.priority ? ` data-priority="${config.priority}"` : '';
281
+ cssHTML = `<style${priorityAttr}>${sanitizeInlineContent(config.inline)}</style>`;
282
+ }
283
+ const position = config.position || 'head';
284
+ if (position === 'head') {
285
+ headHTML += cssHTML;
286
+ }
287
+ else if (position === 'body-start') {
288
+ bodyStartHTML += cssHTML;
289
+ }
290
+ else {
291
+ bodyEndHTML += cssHTML;
292
+ }
293
+ });
294
+ // Generate JS HTML
295
+ sortedJS.forEach((config) => {
296
+ let jsHTML = '';
297
+ if (config.url && isValidAssetUrl(config.url)) {
298
+ const attrs = [];
299
+ if (config.loading === 'immediate') {
300
+ }
301
+ else if (config.loading === 'deferred') {
302
+ attrs.push('defer');
303
+ }
304
+ else if (config.loading === 'lazy') {
305
+ attrs.push('async');
306
+ }
307
+ else {
308
+ if (config.defer)
309
+ attrs.push('defer');
310
+ if (config.async)
311
+ attrs.push('async');
312
+ }
313
+ if (config.integrity)
314
+ attrs.push(`integrity="${config.integrity}"`);
315
+ if (config.crossorigin)
316
+ attrs.push(`crossorigin="${config.crossorigin}"`);
317
+ if (config.priority)
318
+ attrs.push(`data-priority="${config.priority}"`);
319
+ if (config.position)
320
+ attrs.push(`data-position="${config.position}"`);
321
+ jsHTML = `<script src="${config.url}" ${attrs.join(' ')}></script>`;
322
+ }
323
+ else if (config.inline) {
324
+ const priorityAttr = config.priority ? ` data-priority="${config.priority}"` : '';
325
+ const positionAttr = config.position ? ` data-position="${config.position}"` : '';
326
+ jsHTML = `<script${priorityAttr}${positionAttr}>${sanitizeInlineContent(config.inline)}</script>`;
327
+ }
328
+ const position = config.position || (config.loading === 'immediate' ? 'head' : 'body-end');
329
+ if (position === 'head') {
330
+ headHTML += jsHTML;
331
+ }
332
+ else if (position === 'body-start') {
333
+ bodyStartHTML += jsHTML;
334
+ }
335
+ else {
336
+ bodyEndHTML += jsHTML;
337
+ }
338
+ });
339
+ return { headHTML, bodyStartHTML, bodyEndHTML };
340
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Axios Utility Functions
3
+ *
4
+ * Helper functions for creating and configuring Axios instances
5
+ */
6
+ import type { AxiosInstance } from 'axios';
7
+ import type { QSsrContext } from '@quasar/app-vite';
8
+ import type { AppConfig } from '../types/app.types.js';
9
+ /**
10
+ * Validate session token format
11
+ */
12
+ export declare function isValidSessionToken(token: unknown): token is string;
13
+ /**
14
+ * Create Axios instance configured for API requests
15
+ *
16
+ * Handles SSR context, XSRF tokens, session cookies, and base URL resolution
17
+ */
18
+ export declare function createApiInstance(ssrContext?: QSsrContext, appConfig?: Readonly<AppConfig>): AxiosInstance;
19
+ //# sourceMappingURL=axios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../src/utils/axios.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAqB,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAqCrD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CASnE;AAoBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,aAAa,CAmD1G"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Axios Utility Functions
3
+ *
4
+ * Helper functions for creating and configuring Axios instances
5
+ */
6
+ import axios from 'axios';
7
+ import { getSsrKeyHeader } from './headers.js';
8
+ /**
9
+ * Get default XSRF cookie name
10
+ */
11
+ function getDefaultXsrfCookieName() {
12
+ return import.meta.env.XSRF_COOKIE_NAME || 'XSRF-TOKEN';
13
+ }
14
+ /**
15
+ * Get default session cookie name
16
+ */
17
+ function getDefaultSessionCookieName() {
18
+ return import.meta.env.SESSION_COOKIE_NAME || 'laravel_session';
19
+ }
20
+ /**
21
+ * Get XSRF cookie name from AppConfig or SSR context or default
22
+ */
23
+ function getXsrfCookieName(appConfig, ssrContext) {
24
+ // Priority: AppConfig > SSR quvelContext > env default
25
+ return appConfig?.session?.xsrf_cookie
26
+ || ssrContext?.req?.quvelContext?.appConfig?.session?.xsrf_cookie
27
+ || getDefaultXsrfCookieName();
28
+ }
29
+ /**
30
+ * Get the session cookie name from AppConfig or SSR context or default
31
+ */
32
+ function getSessionCookieName(appConfig, ssrContext) {
33
+ // Priority: AppConfig > SSR quvelContext > env default
34
+ return appConfig?.session?.cookie
35
+ || ssrContext?.req?.quvelContext?.appConfig?.session?.cookie
36
+ || getDefaultSessionCookieName();
37
+ }
38
+ /**
39
+ * Validate session token format
40
+ */
41
+ export function isValidSessionToken(token) {
42
+ if (typeof token !== 'string')
43
+ return false;
44
+ try {
45
+ const decoded = decodeURIComponent(token);
46
+ return /^[A-Za-z0-9+/=]{20,512}$/.test(decoded);
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ /**
53
+ * Parse cookies from SSR request
54
+ */
55
+ function parseSsrCookies(ssrServiceOptions) {
56
+ const cookieHeader = ssrServiceOptions?.req?.headers?.cookie;
57
+ if (!cookieHeader)
58
+ return {};
59
+ const cookies = {};
60
+ cookieHeader.split(';').forEach((cookie) => {
61
+ const [name, ...rest] = cookie.split('=');
62
+ if (name && rest.length > 0) {
63
+ cookies[name.trim()] = rest.join('=').trim();
64
+ }
65
+ });
66
+ return cookies;
67
+ }
68
+ /**
69
+ * Create Axios instance configured for API requests
70
+ *
71
+ * Handles SSR context, XSRF tokens, session cookies, and base URL resolution
72
+ */
73
+ export function createApiInstance(ssrContext, appConfig) {
74
+ const baseURL = appConfig?.app?.url || import.meta.env.VITE_API_URL || '';
75
+ if (!baseURL) {
76
+ throw new Error('No API URL configured. Set VITE_API_URL or configure app.url in AppConfig');
77
+ }
78
+ const axiosConfig = {
79
+ baseURL,
80
+ withCredentials: true,
81
+ withXSRFToken: true,
82
+ xsrfCookieName: getXsrfCookieName(appConfig, ssrContext),
83
+ xsrfHeaderName: 'X-XSRF-TOKEN',
84
+ headers: {
85
+ Accept: 'application/json',
86
+ },
87
+ };
88
+ const instance = axios.create(axiosConfig);
89
+ // Detect session cookie presence from AppConfig
90
+ let hasSessionCookie = false;
91
+ if (ssrContext) {
92
+ // SSR: Set up SSR-specific headers and session detection
93
+ if (appConfig?.api?.ssrKey) {
94
+ const ssrKeyHeaderName = getSsrKeyHeader(appConfig);
95
+ instance.defaults.headers.common[ssrKeyHeaderName] = appConfig.api.ssrKey;
96
+ }
97
+ const sessionCookie = getSessionCookieName(appConfig, ssrContext);
98
+ const xsrfCookieName = getXsrfCookieName(appConfig, ssrContext);
99
+ const cookies = parseSsrCookies(ssrContext);
100
+ const sessionToken = cookies[sessionCookie];
101
+ const xsrfToken = cookies[xsrfCookieName];
102
+ instance.defaults.maxRedirects = Number(import.meta.env.SSR_AXIOS_MAX_REDIRECTS || 0);
103
+ instance.defaults.timeout = Number(import.meta.env.SSR_AXIOS_TIMEOUT || 5000);
104
+ if (isValidSessionToken(sessionToken)) {
105
+ instance.defaults.headers.Cookie = `${sessionCookie}=${sessionToken}`;
106
+ if (xsrfToken) {
107
+ hasSessionCookie = true;
108
+ }
109
+ }
110
+ }
111
+ instance.defaults.hasSessionCookie = hasSessionCookie;
112
+ return instance;
113
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Config utility functions
3
+ */
4
+ import type { QSsrContext } from '@quasar/app-vite';
5
+ import type { AppConfig } from '../types/app.types.js';
6
+ /**
7
+ * Create app config from environment variables
8
+ * Works in both client (import.meta.env) and server (process.env) contexts
9
+ */
10
+ export declare function createConfigFromEnv(): AppConfig;
11
+ /**
12
+ * Create app config from SSR context, window, or environment variables
13
+ * Always starts with env baseline, then merges overrides from SSR context or window
14
+ */
15
+ export declare function createConfig(ssrContext?: QSsrContext | null): AppConfig;
16
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CA0B/C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAUvE"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Config utility functions
3
+ */
4
+ /**
5
+ * Create app config from environment variables
6
+ * Works in both client (import.meta.env) and server (process.env) contexts
7
+ */
8
+ export function createConfigFromEnv() {
9
+ const env = (typeof import.meta !== 'undefined' && import.meta.env)
10
+ ? import.meta.env
11
+ : (typeof process !== 'undefined' ? process.env : {});
12
+ const config = {
13
+ app: {
14
+ name: env.VITE_APP_NAME || 'Quasar App',
15
+ url: env.VITE_API_URL || '',
16
+ env: env.VITE_APP_ENV || undefined,
17
+ debug: env.VITE_DEBUG === 'true' ? true : undefined,
18
+ timezone: env.VITE_TIMEZONE || undefined,
19
+ locale: env.VITE_LOCALE || undefined,
20
+ fallback_locale: env.VITE_FALLBACK_LOCALE || undefined,
21
+ },
22
+ frontend: {
23
+ url: env.VITE_APP_URL || '',
24
+ custom_scheme: env.VITE_CUSTOM_SCHEME || undefined,
25
+ },
26
+ session: {
27
+ xsrf_cookie: env.XSRF_COOKIE_NAME || undefined,
28
+ },
29
+ i18nCookie: env.VITE_I18N_COOKIE || undefined,
30
+ };
31
+ return config;
32
+ }
33
+ /**
34
+ * Create app config from SSR context, window, or environment variables
35
+ * Always starts with env baseline, then merges overrides from SSR context or window
36
+ */
37
+ export function createConfig(ssrContext) {
38
+ const baseConfig = createConfigFromEnv();
39
+ if (ssrContext?.req?.quvelContext?.appConfig) {
40
+ return { ...baseConfig, ...ssrContext.req.quvelContext.appConfig };
41
+ }
42
+ else if (typeof window !== 'undefined' && window.__APP_CONFIG__) {
43
+ return { ...baseConfig, ...window.__APP_CONFIG__ };
44
+ }
45
+ else {
46
+ return baseConfig;
47
+ }
48
+ }
@@ -0,0 +1,12 @@
1
+ import type { QSsrContext } from '@quasar/app-vite';
2
+ import { ServiceContainer } from '../container/ServiceContainer.js';
3
+ import type { ServiceClass } from '../container/types.js';
4
+ /**
5
+ * Creates the service container per request
6
+ *
7
+ * @param ssrContext - The SSR context from Quasar (if in SSR mode)
8
+ * @param serviceClasses - Map of service classes to instantiate
9
+ * @returns The fully initialized service container
10
+ */
11
+ export declare function createContainer(ssrContext?: QSsrContext | null, serviceClasses?: Map<string, ServiceClass>): ServiceContainer;
12
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/utils/container.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,UAAU,CAAC,EAAE,WAAW,GAAG,IAAI,EAC/B,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GACzC,gBAAgB,CAElB"}
@@ -0,0 +1,11 @@
1
+ import { ServiceContainer } from '../container/ServiceContainer.js';
2
+ /**
3
+ * Creates the service container per request
4
+ *
5
+ * @param ssrContext - The SSR context from Quasar (if in SSR mode)
6
+ * @param serviceClasses - Map of service classes to instantiate
7
+ * @returns The fully initialized service container
8
+ */
9
+ export function createContainer(ssrContext, serviceClasses) {
10
+ return new ServiceContainer(ssrContext, serviceClasses);
11
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Deep merge utility for configuration objects
3
+ *
4
+ * Recursively merges two objects with the following behavior:
5
+ * - Nested objects are merged recursively
6
+ * - Arrays are concatenated (not replaced)
7
+ * - Primitives from source override target
8
+ * - Null and undefined values are preserved
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const base = { plugins: ['A'], options: { debug: true } };
13
+ * const override = { plugins: ['B'], options: { verbose: true } };
14
+ * deepMerge(base, override);
15
+ * // Result: { plugins: ['A', 'B'], options: { debug: true, verbose: true } }
16
+ * ```
17
+ */
18
+ export declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
19
+ /**
20
+ * Merge multiple configuration objects from left to right
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const merged = mergeConfigs(base, mode, module, override);
25
+ * ```
26
+ */
27
+ export declare function mergeConfigs<T extends Record<string, unknown>>(...configs: Array<Partial<T> | T>): T;
28
+ //# sourceMappingURL=deepMerge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepMerge.d.ts","sourceRoot":"","sources":["../../src/utils/deepMerge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GACjB,CAAC,CA+BH;AAeD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,GAAG,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAChC,CAAC,CAKH"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Deep merge utility for configuration objects
3
+ *
4
+ * Recursively merges two objects with the following behavior:
5
+ * - Nested objects are merged recursively
6
+ * - Arrays are concatenated (not replaced)
7
+ * - Primitives from source override target
8
+ * - Null and undefined values are preserved
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const base = { plugins: ['A'], options: { debug: true } };
13
+ * const override = { plugins: ['B'], options: { verbose: true } };
14
+ * deepMerge(base, override);
15
+ * // Result: { plugins: ['A', 'B'], options: { debug: true, verbose: true } }
16
+ * ```
17
+ */
18
+ export function deepMerge(target, source) {
19
+ const result = { ...target };
20
+ for (const key in source) {
21
+ if (!Object.prototype.hasOwnProperty.call(source, key)) {
22
+ continue;
23
+ }
24
+ const sourceValue = source[key];
25
+ const targetValue = result[key];
26
+ if (Array.isArray(sourceValue) && Array.isArray(targetValue)) {
27
+ result[key] = [...targetValue, ...sourceValue];
28
+ continue;
29
+ }
30
+ if (isPlainObject(sourceValue) &&
31
+ isPlainObject(targetValue)) {
32
+ result[key] = deepMerge(targetValue, sourceValue);
33
+ continue;
34
+ }
35
+ result[key] = sourceValue;
36
+ }
37
+ return result;
38
+ }
39
+ /**
40
+ * Checks if a value is a plain object (not Array, Date, null, etc.)
41
+ */
42
+ function isPlainObject(value) {
43
+ if (typeof value !== 'object' || value === null) {
44
+ return false;
45
+ }
46
+ const proto = Object.getPrototypeOf(value);
47
+ return proto === Object.prototype || proto === null;
48
+ }
49
+ /**
50
+ * Merge multiple configuration objects from left to right
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * const merged = mergeConfigs(base, mode, module, override);
55
+ * ```
56
+ */
57
+ export function mergeConfigs(...configs) {
58
+ return configs.reduce((acc, config) => deepMerge(acc, config), {});
59
+ }