@bloomneo/appkit 1.2.9

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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +902 -0
  3. package/bin/appkit.js +71 -0
  4. package/bin/commands/generate.js +1050 -0
  5. package/bin/templates/backend/README.md.template +39 -0
  6. package/bin/templates/backend/api.http.template +0 -0
  7. package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
  8. package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
  9. package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
  10. package/bin/templates/backend/package.json.template +34 -0
  11. package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
  12. package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
  13. package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
  14. package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
  15. package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
  16. package/bin/templates/backend/src/api/server.ts.template +188 -0
  17. package/bin/templates/backend/tsconfig.api.json.template +24 -0
  18. package/bin/templates/backend/tsconfig.json.template +40 -0
  19. package/bin/templates/feature/feature.http.template +63 -0
  20. package/bin/templates/feature/feature.route.ts.template +36 -0
  21. package/bin/templates/feature/feature.service.ts.template +81 -0
  22. package/bin/templates/feature/feature.types.ts.template +23 -0
  23. package/bin/templates/feature-db/feature.http.template +63 -0
  24. package/bin/templates/feature-db/feature.model.ts.template +74 -0
  25. package/bin/templates/feature-db/feature.route.ts.template +58 -0
  26. package/bin/templates/feature-db/feature.service.ts.template +231 -0
  27. package/bin/templates/feature-db/feature.types.ts.template +25 -0
  28. package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
  29. package/bin/templates/feature-db/seeding/README.md.template +57 -0
  30. package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
  31. package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
  32. package/bin/templates/feature-user/user.http.template +157 -0
  33. package/bin/templates/feature-user/user.model.ts.template +244 -0
  34. package/bin/templates/feature-user/user.route.ts.template +379 -0
  35. package/bin/templates/feature-user/user.seed.js.template +182 -0
  36. package/bin/templates/feature-user/user.service.ts.template +426 -0
  37. package/bin/templates/feature-user/user.types.ts.template +127 -0
  38. package/dist/auth/auth.d.ts +182 -0
  39. package/dist/auth/auth.d.ts.map +1 -0
  40. package/dist/auth/auth.js +477 -0
  41. package/dist/auth/auth.js.map +1 -0
  42. package/dist/auth/defaults.d.ts +104 -0
  43. package/dist/auth/defaults.d.ts.map +1 -0
  44. package/dist/auth/defaults.js +374 -0
  45. package/dist/auth/defaults.js.map +1 -0
  46. package/dist/auth/index.d.ts +70 -0
  47. package/dist/auth/index.d.ts.map +1 -0
  48. package/dist/auth/index.js +94 -0
  49. package/dist/auth/index.js.map +1 -0
  50. package/dist/cache/cache.d.ts +118 -0
  51. package/dist/cache/cache.d.ts.map +1 -0
  52. package/dist/cache/cache.js +249 -0
  53. package/dist/cache/cache.js.map +1 -0
  54. package/dist/cache/defaults.d.ts +63 -0
  55. package/dist/cache/defaults.d.ts.map +1 -0
  56. package/dist/cache/defaults.js +193 -0
  57. package/dist/cache/defaults.js.map +1 -0
  58. package/dist/cache/index.d.ts +101 -0
  59. package/dist/cache/index.d.ts.map +1 -0
  60. package/dist/cache/index.js +203 -0
  61. package/dist/cache/index.js.map +1 -0
  62. package/dist/cache/strategies/memory.d.ts +138 -0
  63. package/dist/cache/strategies/memory.d.ts.map +1 -0
  64. package/dist/cache/strategies/memory.js +348 -0
  65. package/dist/cache/strategies/memory.js.map +1 -0
  66. package/dist/cache/strategies/redis.d.ts +105 -0
  67. package/dist/cache/strategies/redis.d.ts.map +1 -0
  68. package/dist/cache/strategies/redis.js +318 -0
  69. package/dist/cache/strategies/redis.js.map +1 -0
  70. package/dist/config/config.d.ts +62 -0
  71. package/dist/config/config.d.ts.map +1 -0
  72. package/dist/config/config.js +107 -0
  73. package/dist/config/config.js.map +1 -0
  74. package/dist/config/defaults.d.ts +44 -0
  75. package/dist/config/defaults.d.ts.map +1 -0
  76. package/dist/config/defaults.js +217 -0
  77. package/dist/config/defaults.js.map +1 -0
  78. package/dist/config/index.d.ts +105 -0
  79. package/dist/config/index.d.ts.map +1 -0
  80. package/dist/config/index.js +163 -0
  81. package/dist/config/index.js.map +1 -0
  82. package/dist/database/adapters/mongoose.d.ts +106 -0
  83. package/dist/database/adapters/mongoose.d.ts.map +1 -0
  84. package/dist/database/adapters/mongoose.js +480 -0
  85. package/dist/database/adapters/mongoose.js.map +1 -0
  86. package/dist/database/adapters/prisma.d.ts +106 -0
  87. package/dist/database/adapters/prisma.d.ts.map +1 -0
  88. package/dist/database/adapters/prisma.js +494 -0
  89. package/dist/database/adapters/prisma.js.map +1 -0
  90. package/dist/database/defaults.d.ts +87 -0
  91. package/dist/database/defaults.d.ts.map +1 -0
  92. package/dist/database/defaults.js +271 -0
  93. package/dist/database/defaults.js.map +1 -0
  94. package/dist/database/index.d.ts +137 -0
  95. package/dist/database/index.d.ts.map +1 -0
  96. package/dist/database/index.js +490 -0
  97. package/dist/database/index.js.map +1 -0
  98. package/dist/email/defaults.d.ts +100 -0
  99. package/dist/email/defaults.d.ts.map +1 -0
  100. package/dist/email/defaults.js +400 -0
  101. package/dist/email/defaults.js.map +1 -0
  102. package/dist/email/email.d.ts +139 -0
  103. package/dist/email/email.d.ts.map +1 -0
  104. package/dist/email/email.js +316 -0
  105. package/dist/email/email.js.map +1 -0
  106. package/dist/email/index.d.ts +176 -0
  107. package/dist/email/index.d.ts.map +1 -0
  108. package/dist/email/index.js +251 -0
  109. package/dist/email/index.js.map +1 -0
  110. package/dist/email/strategies/console.d.ts +90 -0
  111. package/dist/email/strategies/console.d.ts.map +1 -0
  112. package/dist/email/strategies/console.js +268 -0
  113. package/dist/email/strategies/console.js.map +1 -0
  114. package/dist/email/strategies/resend.d.ts +84 -0
  115. package/dist/email/strategies/resend.d.ts.map +1 -0
  116. package/dist/email/strategies/resend.js +266 -0
  117. package/dist/email/strategies/resend.js.map +1 -0
  118. package/dist/email/strategies/smtp.d.ts +77 -0
  119. package/dist/email/strategies/smtp.d.ts.map +1 -0
  120. package/dist/email/strategies/smtp.js +286 -0
  121. package/dist/email/strategies/smtp.js.map +1 -0
  122. package/dist/error/defaults.d.ts +40 -0
  123. package/dist/error/defaults.d.ts.map +1 -0
  124. package/dist/error/defaults.js +75 -0
  125. package/dist/error/defaults.js.map +1 -0
  126. package/dist/error/error.d.ts +140 -0
  127. package/dist/error/error.d.ts.map +1 -0
  128. package/dist/error/error.js +200 -0
  129. package/dist/error/error.js.map +1 -0
  130. package/dist/error/index.d.ts +145 -0
  131. package/dist/error/index.d.ts.map +1 -0
  132. package/dist/error/index.js +145 -0
  133. package/dist/error/index.js.map +1 -0
  134. package/dist/event/defaults.d.ts +111 -0
  135. package/dist/event/defaults.d.ts.map +1 -0
  136. package/dist/event/defaults.js +378 -0
  137. package/dist/event/defaults.js.map +1 -0
  138. package/dist/event/event.d.ts +171 -0
  139. package/dist/event/event.d.ts.map +1 -0
  140. package/dist/event/event.js +391 -0
  141. package/dist/event/event.js.map +1 -0
  142. package/dist/event/index.d.ts +173 -0
  143. package/dist/event/index.d.ts.map +1 -0
  144. package/dist/event/index.js +302 -0
  145. package/dist/event/index.js.map +1 -0
  146. package/dist/event/strategies/memory.d.ts +122 -0
  147. package/dist/event/strategies/memory.d.ts.map +1 -0
  148. package/dist/event/strategies/memory.js +331 -0
  149. package/dist/event/strategies/memory.js.map +1 -0
  150. package/dist/event/strategies/redis.d.ts +115 -0
  151. package/dist/event/strategies/redis.d.ts.map +1 -0
  152. package/dist/event/strategies/redis.js +434 -0
  153. package/dist/event/strategies/redis.js.map +1 -0
  154. package/dist/index.d.ts +58 -0
  155. package/dist/index.d.ts.map +1 -0
  156. package/dist/index.js +72 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/logger/defaults.d.ts +67 -0
  159. package/dist/logger/defaults.d.ts.map +1 -0
  160. package/dist/logger/defaults.js +213 -0
  161. package/dist/logger/defaults.js.map +1 -0
  162. package/dist/logger/index.d.ts +84 -0
  163. package/dist/logger/index.d.ts.map +1 -0
  164. package/dist/logger/index.js +101 -0
  165. package/dist/logger/index.js.map +1 -0
  166. package/dist/logger/logger.d.ts +165 -0
  167. package/dist/logger/logger.d.ts.map +1 -0
  168. package/dist/logger/logger.js +843 -0
  169. package/dist/logger/logger.js.map +1 -0
  170. package/dist/logger/transports/console.d.ts +102 -0
  171. package/dist/logger/transports/console.d.ts.map +1 -0
  172. package/dist/logger/transports/console.js +276 -0
  173. package/dist/logger/transports/console.js.map +1 -0
  174. package/dist/logger/transports/database.d.ts +153 -0
  175. package/dist/logger/transports/database.d.ts.map +1 -0
  176. package/dist/logger/transports/database.js +539 -0
  177. package/dist/logger/transports/database.js.map +1 -0
  178. package/dist/logger/transports/file.d.ts +146 -0
  179. package/dist/logger/transports/file.d.ts.map +1 -0
  180. package/dist/logger/transports/file.js +464 -0
  181. package/dist/logger/transports/file.js.map +1 -0
  182. package/dist/logger/transports/http.d.ts +128 -0
  183. package/dist/logger/transports/http.d.ts.map +1 -0
  184. package/dist/logger/transports/http.js +401 -0
  185. package/dist/logger/transports/http.js.map +1 -0
  186. package/dist/logger/transports/webhook.d.ts +152 -0
  187. package/dist/logger/transports/webhook.d.ts.map +1 -0
  188. package/dist/logger/transports/webhook.js +485 -0
  189. package/dist/logger/transports/webhook.js.map +1 -0
  190. package/dist/queue/defaults.d.ts +66 -0
  191. package/dist/queue/defaults.d.ts.map +1 -0
  192. package/dist/queue/defaults.js +205 -0
  193. package/dist/queue/defaults.js.map +1 -0
  194. package/dist/queue/index.d.ts +124 -0
  195. package/dist/queue/index.d.ts.map +1 -0
  196. package/dist/queue/index.js +116 -0
  197. package/dist/queue/index.js.map +1 -0
  198. package/dist/queue/queue.d.ts +156 -0
  199. package/dist/queue/queue.d.ts.map +1 -0
  200. package/dist/queue/queue.js +387 -0
  201. package/dist/queue/queue.js.map +1 -0
  202. package/dist/queue/transports/database.d.ts +165 -0
  203. package/dist/queue/transports/database.d.ts.map +1 -0
  204. package/dist/queue/transports/database.js +595 -0
  205. package/dist/queue/transports/database.js.map +1 -0
  206. package/dist/queue/transports/memory.d.ts +143 -0
  207. package/dist/queue/transports/memory.d.ts.map +1 -0
  208. package/dist/queue/transports/memory.js +415 -0
  209. package/dist/queue/transports/memory.js.map +1 -0
  210. package/dist/queue/transports/redis.d.ts +203 -0
  211. package/dist/queue/transports/redis.d.ts.map +1 -0
  212. package/dist/queue/transports/redis.js +744 -0
  213. package/dist/queue/transports/redis.js.map +1 -0
  214. package/dist/security/defaults.d.ts +64 -0
  215. package/dist/security/defaults.d.ts.map +1 -0
  216. package/dist/security/defaults.js +159 -0
  217. package/dist/security/defaults.js.map +1 -0
  218. package/dist/security/index.d.ts +110 -0
  219. package/dist/security/index.d.ts.map +1 -0
  220. package/dist/security/index.js +160 -0
  221. package/dist/security/index.js.map +1 -0
  222. package/dist/security/security.d.ts +138 -0
  223. package/dist/security/security.d.ts.map +1 -0
  224. package/dist/security/security.js +419 -0
  225. package/dist/security/security.js.map +1 -0
  226. package/dist/storage/defaults.d.ts +79 -0
  227. package/dist/storage/defaults.d.ts.map +1 -0
  228. package/dist/storage/defaults.js +358 -0
  229. package/dist/storage/defaults.js.map +1 -0
  230. package/dist/storage/index.d.ts +153 -0
  231. package/dist/storage/index.d.ts.map +1 -0
  232. package/dist/storage/index.js +242 -0
  233. package/dist/storage/index.js.map +1 -0
  234. package/dist/storage/storage.d.ts +151 -0
  235. package/dist/storage/storage.d.ts.map +1 -0
  236. package/dist/storage/storage.js +439 -0
  237. package/dist/storage/storage.js.map +1 -0
  238. package/dist/storage/strategies/local.d.ts +117 -0
  239. package/dist/storage/strategies/local.d.ts.map +1 -0
  240. package/dist/storage/strategies/local.js +368 -0
  241. package/dist/storage/strategies/local.js.map +1 -0
  242. package/dist/storage/strategies/r2.d.ts +130 -0
  243. package/dist/storage/strategies/r2.d.ts.map +1 -0
  244. package/dist/storage/strategies/r2.js +470 -0
  245. package/dist/storage/strategies/r2.js.map +1 -0
  246. package/dist/storage/strategies/s3.d.ts +121 -0
  247. package/dist/storage/strategies/s3.d.ts.map +1 -0
  248. package/dist/storage/strategies/s3.js +461 -0
  249. package/dist/storage/strategies/s3.js.map +1 -0
  250. package/dist/util/defaults.d.ts +77 -0
  251. package/dist/util/defaults.d.ts.map +1 -0
  252. package/dist/util/defaults.js +193 -0
  253. package/dist/util/defaults.js.map +1 -0
  254. package/dist/util/index.d.ts +97 -0
  255. package/dist/util/index.d.ts.map +1 -0
  256. package/dist/util/index.js +165 -0
  257. package/dist/util/index.js.map +1 -0
  258. package/dist/util/util.d.ts +145 -0
  259. package/dist/util/util.d.ts.map +1 -0
  260. package/dist/util/util.js +481 -0
  261. package/dist/util/util.js.map +1 -0
  262. package/package.json +234 -0
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Smart defaults and environment validation for configuration management
3
+ * @module @bloomneo/appkit/config
4
+ * @file src/config/defaults.ts
5
+ *
6
+ * @llm-rule WHEN: App startup - need to parse UPPER_SNAKE_CASE environment variables
7
+ * @llm-rule AVOID: Calling multiple times - expensive parsing, use lazy loading in get()
8
+ * @llm-rule NOTE: Called once at startup, cached globally for performance
9
+ */
10
+ /**
11
+ * Parses a string value to its appropriate type (boolean, number, or string)
12
+ * @llm-rule WHEN: Processing environment variables that need type conversion
13
+ * @llm-rule AVOID: Manual string-to-type conversion - this handles edge cases properly
14
+ * @llm-rule NOTE: Supports "true"/"false" → boolean, numeric strings → number
15
+ */
16
+ function parseValue(value) {
17
+ if (typeof value !== 'string')
18
+ return value;
19
+ const trimmed = value.trim();
20
+ // Handle empty strings
21
+ if (trimmed === '')
22
+ return '';
23
+ // Handle booleans
24
+ const lowerValue = trimmed.toLowerCase();
25
+ if (lowerValue === 'true')
26
+ return true;
27
+ if (lowerValue === 'false')
28
+ return false;
29
+ // Handle special values
30
+ if (lowerValue === 'null')
31
+ return '';
32
+ if (lowerValue === 'undefined')
33
+ return '';
34
+ // Handle numbers (but not if they start with 0 - could be IDs)
35
+ if (!trimmed.startsWith('0') && !isNaN(Number(trimmed)) && trimmed !== '') {
36
+ const num = Number(trimmed);
37
+ // Only convert if it's a safe integer or decimal
38
+ if (Number.isSafeInteger(num) || (num % 1 !== 0 && num.toString() === trimmed)) {
39
+ return num;
40
+ }
41
+ }
42
+ return value;
43
+ }
44
+ /**
45
+ * Sets a value on a nested object using a dot-notation path
46
+ * @llm-rule WHEN: Building nested config object from flat environment variables
47
+ * @llm-rule AVOID: Manual object nesting - this handles deep paths safely
48
+ */
49
+ function setNestedValue(obj, path, value) {
50
+ let current = obj;
51
+ for (let i = 0; i < path.length - 1; i++) {
52
+ const segment = path[i];
53
+ if (typeof current[segment] !== 'object' || current[segment] === null) {
54
+ current[segment] = {};
55
+ }
56
+ current = current[segment];
57
+ }
58
+ current[path[path.length - 1]] = value;
59
+ }
60
+ /**
61
+ * Validates the NODE_ENV for common conventions
62
+ * @llm-rule WHEN: App startup to ensure proper environment configuration
63
+ * @llm-rule AVOID: Skipping validation - improper NODE_ENV causes subtle bugs
64
+ */
65
+ function validateEnvironment() {
66
+ const nodeEnv = process.env.NODE_ENV;
67
+ if (nodeEnv && !['development', 'production', 'test', 'staging'].includes(nodeEnv)) {
68
+ console.warn(`[VoilaJSX AppKit] Unusual NODE_ENV: "${nodeEnv}". ` +
69
+ `Expected: development, production, test, or staging.`);
70
+ }
71
+ // Validate common required variables in production
72
+ if (nodeEnv === 'production') {
73
+ const requiredProdVars = ['VOILA_SERVICE_NAME'];
74
+ const missing = requiredProdVars.filter(varName => !process.env[varName]);
75
+ if (missing.length > 0) {
76
+ console.warn(`[VoilaJSX AppKit] Missing recommended production environment variables: ${missing.join(', ')}`);
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * Check if environment variable is a framework variable that should be ignored
82
+ * @llm-rule WHEN: Filtering out framework variables from app config parsing
83
+ * @llm-rule AVOID: Parsing framework variables as app config - they serve different purposes
84
+ * @llm-rule NOTE: VoilaJSX AppKit uses VOILA_* and FLUX_* for internal configuration
85
+ */
86
+ function isFrameworkVariable(envKey) {
87
+ const frameworkPrefixes = [
88
+ 'VOILA_', // VoilaJSX AppKit framework configuration
89
+ 'FLUX_', // Flux Framework internal variables
90
+ 'NODE_', // Node.js environment variables
91
+ 'npm_', // npm variables
92
+ ];
93
+ return frameworkPrefixes.some(prefix => envKey.startsWith(prefix));
94
+ }
95
+ /**
96
+ * Check if environment variable is a system variable that should be ignored
97
+ * @llm-rule WHEN: Filtering out system variables from app config validation
98
+ * @llm-rule AVOID: Validating system variables - they don't follow our conventions
99
+ */
100
+ function isSystemVariable(envKey) {
101
+ const systemVarPrefixes = [
102
+ '__CF', // macOS Core Foundation variables
103
+ '__VERCEL_', // Vercel deployment variables
104
+ '__NEXT_', // Next.js internal variables
105
+ '_', // Shell variables starting with underscore
106
+ 'TERM', // Terminal variables
107
+ 'SHELL', // Shell variables
108
+ 'PATH', // System PATH
109
+ 'HOME', // User home directory
110
+ 'USER', // Current user
111
+ 'PWD', // Present working directory
112
+ 'OLDPWD', // Previous working directory
113
+ 'SHLVL', // Shell level
114
+ 'PS1', // Primary prompt string
115
+ 'LANG', // Language settings
116
+ 'LC_', // Locale settings
117
+ 'XDG_', // XDG Base Directory variables
118
+ ];
119
+ // Check system variable prefixes
120
+ if (systemVarPrefixes.some(prefix => envKey.startsWith(prefix))) {
121
+ return true;
122
+ }
123
+ // Check for common system variables
124
+ const systemVars = [
125
+ 'TMPDIR', 'TMP', 'TEMP',
126
+ 'EDITOR', 'VISUAL',
127
+ 'PAGER', 'LESS',
128
+ 'DISPLAY', 'XAUTHORITY',
129
+ 'SSH_AUTH_SOCK', 'SSH_AGENT_PID',
130
+ 'CONDA_DEFAULT_ENV', 'VIRTUAL_ENV',
131
+ 'JAVA_HOME', 'ANDROID_HOME',
132
+ 'DOCKER_HOST', 'KUBERNETES_SERVICE_HOST',
133
+ 'CI', 'GITHUB_ACTIONS', 'GITLAB_CI', 'JENKINS_URL',
134
+ ];
135
+ return systemVars.includes(envKey);
136
+ }
137
+ /**
138
+ * Validates environment variable format for common mistakes
139
+ * @llm-rule WHEN: Processing custom environment variables for format validation
140
+ * @llm-rule AVOID: Silent format errors - validates UPPER_SNAKE_CASE convention
141
+ */
142
+ function validateEnvVarFormat(envKey) {
143
+ // Skip framework and system variables - they don't follow our conventions
144
+ if (isFrameworkVariable(envKey) || isSystemVariable(envKey)) {
145
+ return true;
146
+ }
147
+ // Check for proper UPPER_SNAKE_CASE format
148
+ if (envKey !== envKey.toUpperCase()) {
149
+ console.warn(`[VoilaJSX AppKit] Environment variable "${envKey}" should be uppercase for consistency`);
150
+ }
151
+ return true;
152
+ }
153
+ /**
154
+ * Builds the entire configuration object from process.env
155
+ * @llm-rule WHEN: App startup to get production-ready configuration from environment
156
+ * @llm-rule AVOID: Calling repeatedly - validates environment each time, expensive operation
157
+ * @llm-rule NOTE: Called once at startup, cached globally for performance
158
+ * @llm-rule CONVENTION: Only processes non-framework variables for user config
159
+ * @llm-rule CONVENTION: Variables with VOILA_* and FLUX_* are AppKit internal
160
+ */
161
+ export function buildConfigFromEnv() {
162
+ validateEnvironment();
163
+ const config = {
164
+ app: {
165
+ name: process.env.VOILA_SERVICE_NAME || process.env.npm_package_name || 'voila-app',
166
+ environment: process.env.NODE_ENV || 'development',
167
+ port: process.env.PORT ? parseInt(process.env.PORT, 10) : undefined,
168
+ host: process.env.HOST || undefined,
169
+ },
170
+ };
171
+ // Process ONLY user configuration variables using UPPER_SNAKE_CASE convention
172
+ // IMPORTANT: Framework variables (VOILA_*, FLUX_*) are NOT processed as user config
173
+ for (const envKey in process.env) {
174
+ // Skip framework variables and system variables
175
+ if (isFrameworkVariable(envKey) || isSystemVariable(envKey)) {
176
+ continue;
177
+ }
178
+ // Process remaining variables as user configuration
179
+ if (validateEnvVarFormat(envKey)) {
180
+ const path = envKey.toLowerCase().split('_');
181
+ const value = parseValue(process.env[envKey] || '');
182
+ setNestedValue(config, path, value);
183
+ }
184
+ }
185
+ return config;
186
+ }
187
+ /**
188
+ * Validates critical configuration at startup
189
+ * @llm-rule WHEN: App startup to ensure required config is present
190
+ * @llm-rule AVOID: Skipping validation - missing config causes runtime errors
191
+ * @llm-rule NOTE: Add your app-specific required config here
192
+ */
193
+ export function validateConfig(config) {
194
+ const environment = config.app.environment;
195
+ // Production-specific validations
196
+ if (environment === 'production') {
197
+ if (!config.app.name || config.app.name === 'voila-app') {
198
+ throw new Error('VOILA_SERVICE_NAME is required in production. ' +
199
+ 'Set environment variable: VOILA_SERVICE_NAME=your-app-name');
200
+ }
201
+ }
202
+ // Port validation
203
+ if (config.app.port && (config.app.port < 1 || config.app.port > 65535)) {
204
+ throw new Error(`Invalid PORT: ${config.app.port}. Must be between 1 and 65535.`);
205
+ }
206
+ }
207
+ /**
208
+ * Gets smart defaults with validation
209
+ * @llm-rule WHEN: App startup to get production-ready configuration
210
+ * @llm-rule AVOID: Calling repeatedly - expensive validation, cache the result
211
+ */
212
+ export function getSmartDefaults() {
213
+ const config = buildConfigFromEnv();
214
+ validateConfig(config);
215
+ return config;
216
+ }
217
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Ultra-simple configuration management that just works
3
+ * @module @bloomneo/appkit/config
4
+ * @file src/config/index.ts
5
+ *
6
+ * @llm-rule WHEN: Building apps that need configuration from environment variables
7
+ * @llm-rule AVOID: Complex config setups with multiple files - this handles everything automatically
8
+ * @llm-rule NOTE: Uses UPPER_SNAKE_CASE convention (DATABASE_HOST → config.get('database.host'))
9
+ * @llm-rule NOTE: Common pattern - configClass.get() → config.get('path', default) → use value
10
+ *
11
+ * CRITICAL UNDERSCORE CONVENTION:
12
+ * - VOILA_* and FLUX_* = Framework internal variables (NOT parsed as app config)
13
+ * - Everything else = Your app config (parsed into config object)
14
+ *
15
+ * Examples:
16
+ * ✅ VOILA_AUTH_SECRET=secret → Framework internal (not in config object)
17
+ * ✅ DATABASE_HOST=localhost → config.get('database.host')
18
+ * ✅ REDIS_URL=redis://local → config.get('redis.url')
19
+ * ❌ VOILA_DATABASE_HOST=localhost → Framework var (won't be parsed as app config)
20
+ */
21
+ import { ConfigClass } from './config.js';
22
+ import { type ConfigValue } from './defaults.js';
23
+ /**
24
+ * Get configuration instance - the only function you need to learn
25
+ * Environment variables parsed once for performance
26
+ * @llm-rule WHEN: Starting any operation that needs configuration - this is your main entry point
27
+ * @llm-rule AVOID: Calling new ConfigClass() directly - always use this function
28
+ * @llm-rule NOTE: Typical flow - get() → config.get('path') → use value
29
+ * @llm-rule NOTE: Only parses non-framework variables for your app config
30
+ */
31
+ declare function get(overrides?: ConfigValue): ConfigClass;
32
+ /**
33
+ * Reset global instance (useful for testing or config changes)
34
+ * @llm-rule WHEN: Testing config logic with different environment variables
35
+ * @llm-rule AVOID: Using in production - only for tests and development
36
+ */
37
+ declare function reset(newConfig?: ConfigValue): ConfigClass;
38
+ /**
39
+ * Clear the cached configuration instance
40
+ * @llm-rule WHEN: Testing or when you need to reload environment variables
41
+ * @llm-rule AVOID: Using in production - only for tests and development
42
+ */
43
+ declare function clearCache(): void;
44
+ /**
45
+ * Get current environment (development, production, test)
46
+ * @llm-rule WHEN: Need to conditionally enable features based on environment
47
+ * @llm-rule AVOID: Checking process.env.NODE_ENV directly - use this for consistency
48
+ */
49
+ declare function getEnvironment(): string;
50
+ /**
51
+ * Check if running in development mode
52
+ * @llm-rule WHEN: Need to enable debug features or detailed logging
53
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
54
+ */
55
+ declare function isDevelopment(): boolean;
56
+ /**
57
+ * Check if running in production mode
58
+ * @llm-rule WHEN: Need to disable debug features or enable optimizations
59
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
60
+ */
61
+ declare function isProduction(): boolean;
62
+ /**
63
+ * Check if running in test mode
64
+ * @llm-rule WHEN: Need to enable test-specific behavior
65
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
66
+ */
67
+ declare function isTest(): boolean;
68
+ /**
69
+ * Get all environment variables that follow the UPPER_SNAKE_CASE convention
70
+ * @llm-rule WHEN: Debugging configuration or documenting available config options
71
+ * @llm-rule AVOID: Using for runtime config access - use get() instead
72
+ * @llm-rule NOTE: Only returns non-framework variables - your app config
73
+ */
74
+ declare function getEnvVars(): Record<string, string>;
75
+ /**
76
+ * Validate that required configuration paths exist
77
+ * @llm-rule WHEN: App startup to ensure critical config is present
78
+ * @llm-rule AVOID: Using in request handlers - expensive validation
79
+ * @llm-rule NOTE: Throws descriptive errors with environment variable names
80
+ */
81
+ declare function validateRequired(paths: string[]): void;
82
+ /**
83
+ * Get configuration for a specific module/feature
84
+ * @llm-rule WHEN: Module initialization that needs multiple related config values
85
+ * @llm-rule AVOID: Multiple get() calls - use this for better performance
86
+ */
87
+ declare function getModuleConfig<T extends Record<string, any>>(modulePrefix: string, defaults?: T): T;
88
+ /**
89
+ * Single configuration export with enhanced functionality
90
+ */
91
+ export declare const configClass: {
92
+ readonly get: typeof get;
93
+ readonly reset: typeof reset;
94
+ readonly clearCache: typeof clearCache;
95
+ readonly getEnvironment: typeof getEnvironment;
96
+ readonly isDevelopment: typeof isDevelopment;
97
+ readonly isProduction: typeof isProduction;
98
+ readonly isTest: typeof isTest;
99
+ readonly getEnvVars: typeof getEnvVars;
100
+ readonly validateRequired: typeof validateRequired;
101
+ readonly getModuleConfig: typeof getModuleConfig;
102
+ };
103
+ export type { ConfigValue, AppConfig } from './defaults.js';
104
+ export { ConfigClass } from './config.js';
105
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAKnF;;;;;;;GAOG;AACH,iBAAS,GAAG,CAAC,SAAS,GAAE,WAAgB,GAAG,WAAW,CASrD;AAED;;;;GAIG;AACH,iBAAS,KAAK,CAAC,SAAS,GAAE,WAAgB,GAAG,WAAW,CAKvD;AAED;;;;GAIG;AACH,iBAAS,UAAU,IAAI,IAAI,CAE1B;AAED;;;;GAIG;AACH,iBAAS,cAAc,IAAI,MAAM,CAGhC;AAED;;;;GAIG;AACH,iBAAS,aAAa,IAAI,OAAO,CAEhC;AAED;;;;GAIG;AACH,iBAAS,YAAY,IAAI,OAAO,CAE/B;AAED;;;;GAIG;AACH,iBAAS,MAAM,IAAI,OAAO,CAEzB;AAED;;;;;GAKG;AACH,iBAAS,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAe5C;AAED;;;;;GAKG;AACH,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAiB/C;AAED;;;;GAIG;AACH,iBAAS,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACpD,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,CAAW,GACpB,CAAC,CAKH;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;CAgBd,CAAC;AAGX,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Ultra-simple configuration management that just works
3
+ * @module @bloomneo/appkit/config
4
+ * @file src/config/index.ts
5
+ *
6
+ * @llm-rule WHEN: Building apps that need configuration from environment variables
7
+ * @llm-rule AVOID: Complex config setups with multiple files - this handles everything automatically
8
+ * @llm-rule NOTE: Uses UPPER_SNAKE_CASE convention (DATABASE_HOST → config.get('database.host'))
9
+ * @llm-rule NOTE: Common pattern - configClass.get() → config.get('path', default) → use value
10
+ *
11
+ * CRITICAL UNDERSCORE CONVENTION:
12
+ * - VOILA_* and FLUX_* = Framework internal variables (NOT parsed as app config)
13
+ * - Everything else = Your app config (parsed into config object)
14
+ *
15
+ * Examples:
16
+ * ✅ VOILA_AUTH_SECRET=secret → Framework internal (not in config object)
17
+ * ✅ DATABASE_HOST=localhost → config.get('database.host')
18
+ * ✅ REDIS_URL=redis://local → config.get('redis.url')
19
+ * ❌ VOILA_DATABASE_HOST=localhost → Framework var (won't be parsed as app config)
20
+ */
21
+ import { ConfigClass } from './config.js';
22
+ import { getSmartDefaults } from './defaults.js';
23
+ // Global configuration instance for performance
24
+ let globalConfig = null;
25
+ /**
26
+ * Get configuration instance - the only function you need to learn
27
+ * Environment variables parsed once for performance
28
+ * @llm-rule WHEN: Starting any operation that needs configuration - this is your main entry point
29
+ * @llm-rule AVOID: Calling new ConfigClass() directly - always use this function
30
+ * @llm-rule NOTE: Typical flow - get() → config.get('path') → use value
31
+ * @llm-rule NOTE: Only parses non-framework variables for your app config
32
+ */
33
+ function get(overrides = {}) {
34
+ // Lazy initialization - parse environment once
35
+ if (!globalConfig) {
36
+ const defaults = getSmartDefaults();
37
+ const finalConfig = { ...defaults, ...overrides };
38
+ globalConfig = new ConfigClass(finalConfig);
39
+ }
40
+ return globalConfig;
41
+ }
42
+ /**
43
+ * Reset global instance (useful for testing or config changes)
44
+ * @llm-rule WHEN: Testing config logic with different environment variables
45
+ * @llm-rule AVOID: Using in production - only for tests and development
46
+ */
47
+ function reset(newConfig = {}) {
48
+ const defaults = getSmartDefaults();
49
+ const finalConfig = { ...defaults, ...newConfig };
50
+ globalConfig = new ConfigClass(finalConfig);
51
+ return globalConfig;
52
+ }
53
+ /**
54
+ * Clear the cached configuration instance
55
+ * @llm-rule WHEN: Testing or when you need to reload environment variables
56
+ * @llm-rule AVOID: Using in production - only for tests and development
57
+ */
58
+ function clearCache() {
59
+ globalConfig = null;
60
+ }
61
+ /**
62
+ * Get current environment (development, production, test)
63
+ * @llm-rule WHEN: Need to conditionally enable features based on environment
64
+ * @llm-rule AVOID: Checking process.env.NODE_ENV directly - use this for consistency
65
+ */
66
+ function getEnvironment() {
67
+ const config = get();
68
+ return config.get('app.environment', 'development') || 'development';
69
+ }
70
+ /**
71
+ * Check if running in development mode
72
+ * @llm-rule WHEN: Need to enable debug features or detailed logging
73
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
74
+ */
75
+ function isDevelopment() {
76
+ return getEnvironment() === 'development';
77
+ }
78
+ /**
79
+ * Check if running in production mode
80
+ * @llm-rule WHEN: Need to disable debug features or enable optimizations
81
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
82
+ */
83
+ function isProduction() {
84
+ return getEnvironment() === 'production';
85
+ }
86
+ /**
87
+ * Check if running in test mode
88
+ * @llm-rule WHEN: Need to enable test-specific behavior
89
+ * @llm-rule AVOID: Manual environment checks - use this for consistency
90
+ */
91
+ function isTest() {
92
+ return getEnvironment() === 'test';
93
+ }
94
+ /**
95
+ * Get all environment variables that follow the UPPER_SNAKE_CASE convention
96
+ * @llm-rule WHEN: Debugging configuration or documenting available config options
97
+ * @llm-rule AVOID: Using for runtime config access - use get() instead
98
+ * @llm-rule NOTE: Only returns non-framework variables - your app config
99
+ */
100
+ function getEnvVars() {
101
+ const envVars = {};
102
+ for (const [key, value] of Object.entries(process.env)) {
103
+ // Skip framework variables - only show app config
104
+ if (!key.startsWith('VOILA_') &&
105
+ !key.startsWith('FLUX_') &&
106
+ !key.startsWith('NODE_') &&
107
+ !key.startsWith('npm_') &&
108
+ value !== undefined) {
109
+ envVars[key] = value;
110
+ }
111
+ }
112
+ return envVars;
113
+ }
114
+ /**
115
+ * Validate that required configuration paths exist
116
+ * @llm-rule WHEN: App startup to ensure critical config is present
117
+ * @llm-rule AVOID: Using in request handlers - expensive validation
118
+ * @llm-rule NOTE: Throws descriptive errors with environment variable names
119
+ */
120
+ function validateRequired(paths) {
121
+ const config = get();
122
+ const missing = [];
123
+ for (const path of paths) {
124
+ if (!config.has(path)) {
125
+ missing.push(path);
126
+ }
127
+ }
128
+ if (missing.length > 0) {
129
+ const envVars = missing.map(path => path.split('.').join('_').toUpperCase());
130
+ throw new Error(`Missing required configuration: ${missing.join(', ')}\n` +
131
+ `Set environment variables: ${envVars.join(', ')}`);
132
+ }
133
+ }
134
+ /**
135
+ * Get configuration for a specific module/feature
136
+ * @llm-rule WHEN: Module initialization that needs multiple related config values
137
+ * @llm-rule AVOID: Multiple get() calls - use this for better performance
138
+ */
139
+ function getModuleConfig(modulePrefix, defaults = {}) {
140
+ const config = get();
141
+ const moduleConfig = config.get(modulePrefix, {});
142
+ return { ...defaults, ...moduleConfig };
143
+ }
144
+ /**
145
+ * Single configuration export with enhanced functionality
146
+ */
147
+ export const configClass = {
148
+ // Core methods
149
+ get,
150
+ reset,
151
+ clearCache,
152
+ // Environment helpers
153
+ getEnvironment,
154
+ isDevelopment,
155
+ isProduction,
156
+ isTest,
157
+ // Utility methods
158
+ getEnvVars,
159
+ validateRequired,
160
+ getModuleConfig,
161
+ };
162
+ export { ConfigClass } from './config.js';
163
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Simplified Mongoose adapter with app discovery and tenant middleware
3
+ * @module @bloomneo/appkit/database
4
+ * @file src/database/adapters/mongoose.ts
5
+ *
6
+ * @llm-rule WHEN: Using Mongoose ODM with MongoDB databases in VoilaJSX framework
7
+ * @llm-rule AVOID: Using with SQL databases - use prisma adapter instead
8
+ * @llm-rule NOTE: Auto-discovers apps from /apps directory structure, applies tenant filtering
9
+ */
10
+ interface MongooseClientConfig {
11
+ url: string;
12
+ appName?: string;
13
+ maxPoolSize?: number;
14
+ timeout?: number;
15
+ connectionOptions?: Record<string, any>;
16
+ }
17
+ interface DiscoveredApp {
18
+ name: string;
19
+ modelsPath: string;
20
+ }
21
+ interface TenantMiddlewareOptions {
22
+ fieldName?: string;
23
+ orgId?: string;
24
+ }
25
+ interface MongooseConnection {
26
+ db: any;
27
+ close: () => Promise<void>;
28
+ model: (name: string, schema?: any, collection?: string) => any;
29
+ models: Record<string, any>;
30
+ on: (event: string, callback: (...args: any[]) => void) => void;
31
+ _appKit?: boolean;
32
+ _appName?: string;
33
+ _url?: string;
34
+ _tenantId?: string;
35
+ _tenantFiltered?: boolean;
36
+ [key: string]: any;
37
+ }
38
+ /**
39
+ * Simplified Mongoose adapter with VoilaJSX app discovery
40
+ */
41
+ export declare class MongooseAdapter {
42
+ private options;
43
+ private connections;
44
+ private discoveredApps;
45
+ private isDevelopment;
46
+ private mongoose;
47
+ constructor(options?: Record<string, any>);
48
+ /**
49
+ * Creates Mongoose connection with app discovery and automatic connection management
50
+ */
51
+ createClient(config: MongooseClientConfig): Promise<MongooseConnection>;
52
+ /**
53
+ * Apply tenant filtering middleware to Mongoose connection
54
+ */
55
+ applyTenantMiddleware(connection: MongooseConnection, tenantId: string, options?: TenantMiddlewareOptions): Promise<MongooseConnection>;
56
+ /**
57
+ * Auto-discover VoilaJSX apps with Mongoose models
58
+ */
59
+ discoverApps(): Promise<DiscoveredApp[]>;
60
+ /**
61
+ * Check if tenant registry collection exists
62
+ */
63
+ hasTenantRegistry(connection: MongooseConnection): Promise<boolean>;
64
+ /**
65
+ * Create tenant registry entry
66
+ */
67
+ createTenantRegistryEntry(connection: MongooseConnection, tenantId: string): Promise<void>;
68
+ /**
69
+ * Delete tenant registry entry
70
+ */
71
+ deleteTenantRegistryEntry(connection: MongooseConnection, tenantId: string): Promise<void>;
72
+ /**
73
+ * Check if tenant exists in registry
74
+ */
75
+ tenantExistsInRegistry(connection: MongooseConnection, tenantId: string): Promise<boolean>;
76
+ /**
77
+ * Get all tenants from registry
78
+ */
79
+ getTenantsFromRegistry(connection: MongooseConnection): Promise<string[]>;
80
+ /**
81
+ * Disconnect all cached connections
82
+ */
83
+ disconnect(): Promise<void>;
84
+ /**
85
+ * Detect current app from file path (VoilaJSX structure)
86
+ */
87
+ private _detectCurrentApp;
88
+ /**
89
+ * Find apps directory in project structure
90
+ */
91
+ private _findAppsDirectory;
92
+ /**
93
+ * Load models for specific app
94
+ */
95
+ private _loadModelsForApp;
96
+ /**
97
+ * Setup connection event handlers
98
+ */
99
+ private _setupConnectionEvents;
100
+ /**
101
+ * Mask URL for logging (hide credentials)
102
+ */
103
+ private _maskUrl;
104
+ }
105
+ export {};
106
+ //# sourceMappingURL=mongoose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongoose.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/mongoose.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,UAAU,oBAAoB;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACzC;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,uBAAuB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,kBAAkB;IAC1B,EAAE,EAAE,GAAG,CAAC;IACR,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAChE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,QAAQ,CAAM;gBAEV,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAY7C;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuD7E;;OAEG;IACG,qBAAqB,CACzB,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC;IA4H9B;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAiE9C;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAczE;;OAEG;IACG,yBAAyB,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhG;;OAEG;IACG,yBAAyB,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhG;;OAEG;IACG,sBAAsB,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUhG;;OAEG;IACG,sBAAsB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmB/E;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBjC;;OAEG;YACW,iBAAiB;IAmC/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;YACW,iBAAiB;IA0C/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAwB9B;;OAEG;IACH,OAAO,CAAC,QAAQ;CAQjB"}