create-fluxstack 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/create-fluxstack.ts +2 -3
  2. package/package.json +1 -1
  3. package/.env +0 -30
  4. package/LICENSE +0 -21
  5. package/app/client/README.md +0 -69
  6. package/app/client/frontend-only.ts +0 -12
  7. package/app/client/index.html +0 -13
  8. package/app/client/public/vite.svg +0 -1
  9. package/app/client/src/App.css +0 -883
  10. package/app/client/src/App.tsx +0 -669
  11. package/app/client/src/assets/react.svg +0 -1
  12. package/app/client/src/components/TestPage.tsx +0 -453
  13. package/app/client/src/index.css +0 -51
  14. package/app/client/src/lib/eden-api.ts +0 -110
  15. package/app/client/src/main.tsx +0 -10
  16. package/app/client/src/vite-env.d.ts +0 -1
  17. package/app/client/tsconfig.app.json +0 -43
  18. package/app/client/tsconfig.json +0 -7
  19. package/app/client/tsconfig.node.json +0 -25
  20. package/app/server/app.ts +0 -10
  21. package/app/server/backend-only.ts +0 -15
  22. package/app/server/controllers/users.controller.ts +0 -69
  23. package/app/server/index.ts +0 -104
  24. package/app/server/routes/index.ts +0 -25
  25. package/app/server/routes/users.routes.ts +0 -121
  26. package/app/server/types/index.ts +0 -1
  27. package/app/shared/types/index.ts +0 -18
  28. package/bun.lock +0 -1053
  29. package/core/__tests__/integration.test.ts +0 -227
  30. package/core/build/index.ts +0 -186
  31. package/core/cli/command-registry.ts +0 -334
  32. package/core/cli/index.ts +0 -394
  33. package/core/cli/plugin-discovery.ts +0 -200
  34. package/core/client/standalone.ts +0 -57
  35. package/core/config/__tests__/config-loader.test.ts +0 -591
  36. package/core/config/__tests__/config-merger.test.ts +0 -657
  37. package/core/config/__tests__/env-converter.test.ts +0 -372
  38. package/core/config/__tests__/env-processor.test.ts +0 -431
  39. package/core/config/__tests__/env.test.ts +0 -452
  40. package/core/config/__tests__/integration.test.ts +0 -418
  41. package/core/config/__tests__/loader.test.ts +0 -331
  42. package/core/config/__tests__/schema.test.ts +0 -129
  43. package/core/config/__tests__/validator.test.ts +0 -318
  44. package/core/config/env-dynamic.ts +0 -326
  45. package/core/config/env.ts +0 -597
  46. package/core/config/index.ts +0 -317
  47. package/core/config/loader.ts +0 -546
  48. package/core/config/runtime-config.ts +0 -322
  49. package/core/config/schema.ts +0 -694
  50. package/core/config/validator.ts +0 -540
  51. package/core/framework/__tests__/server.test.ts +0 -233
  52. package/core/framework/client.ts +0 -132
  53. package/core/framework/index.ts +0 -8
  54. package/core/framework/server.ts +0 -501
  55. package/core/framework/types.ts +0 -63
  56. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  57. package/core/plugins/__tests__/manager.test.ts +0 -398
  58. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  59. package/core/plugins/__tests__/registry.test.ts +0 -335
  60. package/core/plugins/built-in/index.ts +0 -142
  61. package/core/plugins/built-in/logger/index.ts +0 -180
  62. package/core/plugins/built-in/monitoring/README.md +0 -193
  63. package/core/plugins/built-in/monitoring/index.ts +0 -912
  64. package/core/plugins/built-in/static/index.ts +0 -289
  65. package/core/plugins/built-in/swagger/index.ts +0 -229
  66. package/core/plugins/built-in/vite/index.ts +0 -316
  67. package/core/plugins/config.ts +0 -348
  68. package/core/plugins/discovery.ts +0 -350
  69. package/core/plugins/executor.ts +0 -351
  70. package/core/plugins/index.ts +0 -195
  71. package/core/plugins/manager.ts +0 -583
  72. package/core/plugins/registry.ts +0 -424
  73. package/core/plugins/types.ts +0 -254
  74. package/core/server/framework.ts +0 -123
  75. package/core/server/index.ts +0 -8
  76. package/core/server/plugins/database.ts +0 -182
  77. package/core/server/plugins/logger.ts +0 -47
  78. package/core/server/plugins/swagger.ts +0 -34
  79. package/core/server/standalone.ts +0 -91
  80. package/core/templates/create-project.ts +0 -455
  81. package/core/types/api.ts +0 -169
  82. package/core/types/build.ts +0 -174
  83. package/core/types/config.ts +0 -68
  84. package/core/types/index.ts +0 -127
  85. package/core/types/plugin.ts +0 -94
  86. package/core/utils/__tests__/errors.test.ts +0 -139
  87. package/core/utils/__tests__/helpers.test.ts +0 -297
  88. package/core/utils/__tests__/logger.test.ts +0 -141
  89. package/core/utils/env-runtime-v2.ts +0 -232
  90. package/core/utils/env-runtime.ts +0 -252
  91. package/core/utils/errors/codes.ts +0 -115
  92. package/core/utils/errors/handlers.ts +0 -63
  93. package/core/utils/errors/index.ts +0 -81
  94. package/core/utils/helpers.ts +0 -180
  95. package/core/utils/index.ts +0 -18
  96. package/core/utils/logger/index.ts +0 -161
  97. package/core/utils/logger.ts +0 -106
  98. package/core/utils/monitoring/index.ts +0 -212
  99. package/tsconfig.json +0 -51
  100. package/vite.config.ts +0 -42
@@ -1,161 +0,0 @@
1
- /**
2
- * FluxStack Logger
3
- * Environment-aware logging system
4
- */
5
-
6
- // Environment info is handled via process.env directly
7
-
8
- type LogLevel = 'debug' | 'info' | 'warn' | 'error'
9
-
10
- export interface Logger {
11
- debug(message: string, meta?: any): void
12
- info(message: string, meta?: any): void
13
- warn(message: string, meta?: any): void
14
- error(message: string, meta?: any): void
15
-
16
- // Contextual logging
17
- child(context: any): Logger
18
-
19
- // Performance logging
20
- time(label: string): void
21
- timeEnd(label: string): void
22
-
23
- // Request logging
24
- request(method: string, path: string, status?: number, duration?: number): void
25
- }
26
-
27
- class FluxStackLogger implements Logger {
28
- private static instance: FluxStackLogger | null = null
29
- private logLevel: LogLevel
30
- private context: any = {}
31
- private timers: Map<string, number> = new Map()
32
-
33
- private constructor(context?: any) {
34
- // Default to 'info' level, can be overridden by config
35
- this.logLevel = (process.env.LOG_LEVEL as LogLevel) || 'info'
36
- this.context = context || {}
37
- }
38
-
39
- static getInstance(): FluxStackLogger {
40
- if (FluxStackLogger.instance === null) {
41
- FluxStackLogger.instance = new FluxStackLogger()
42
- }
43
- return FluxStackLogger.instance
44
- }
45
-
46
- private shouldLog(level: LogLevel): boolean {
47
- const levels: Record<LogLevel, number> = {
48
- debug: 0,
49
- info: 1,
50
- warn: 2,
51
- error: 3
52
- }
53
-
54
- return levels[level] >= levels[this.logLevel]
55
- }
56
-
57
- private formatMessage(level: LogLevel, message: string, meta?: any): string {
58
- const timestamp = new Date().toISOString()
59
- const levelStr = level.toUpperCase().padEnd(5)
60
-
61
- let formatted = `[${timestamp}] ${levelStr}`
62
-
63
- // Add context if available
64
- if (Object.keys(this.context).length > 0) {
65
- const contextStr = Object.entries(this.context)
66
- .map(([key, value]) => `${key}=${value}`)
67
- .join(' ')
68
- formatted += ` [${contextStr}]`
69
- }
70
-
71
- formatted += ` ${message}`
72
-
73
- if (meta && typeof meta === 'object') {
74
- formatted += ` ${JSON.stringify(meta)}`
75
- } else if (meta !== undefined) {
76
- formatted += ` ${meta}`
77
- }
78
-
79
- return formatted
80
- }
81
-
82
- debug(message: string, meta?: any): void {
83
- if (this.shouldLog('debug')) {
84
- console.debug(this.formatMessage('debug', message, meta))
85
- }
86
- }
87
-
88
- info(message: string, meta?: any): void {
89
- if (this.shouldLog('info')) {
90
- console.info(this.formatMessage('info', message, meta))
91
- }
92
- }
93
-
94
- warn(message: string, meta?: any): void {
95
- if (this.shouldLog('warn')) {
96
- console.warn(this.formatMessage('warn', message, meta))
97
- }
98
- }
99
-
100
- error(message: string, meta?: any): void {
101
- if (this.shouldLog('error')) {
102
- console.error(this.formatMessage('error', message, meta))
103
- }
104
- }
105
-
106
- // Contextual logging
107
- child(context: any): FluxStackLogger {
108
- return new FluxStackLogger({ ...this.context, ...context })
109
- }
110
-
111
- // Performance logging
112
- time(label: string): void {
113
- this.timers.set(label, Date.now())
114
- }
115
-
116
- timeEnd(label: string): void {
117
- const startTime = this.timers.get(label)
118
- if (startTime) {
119
- const duration = Date.now() - startTime
120
- this.info(`Timer ${label}: ${duration}ms`)
121
- this.timers.delete(label)
122
- }
123
- }
124
-
125
- // HTTP request logging
126
- request(method: string, path: string, status?: number, duration?: number): void {
127
- const statusStr = status ? ` ${status}` : ''
128
- const durationStr = duration ? ` (${duration}ms)` : ''
129
- this.info(`${method} ${path}${statusStr}${durationStr}`)
130
- }
131
-
132
- // Plugin logging
133
- plugin(pluginName: string, message: string, meta?: any): void {
134
- this.debug(`[${pluginName}] ${message}`, meta)
135
- }
136
-
137
- // Framework logging
138
- framework(message: string, meta?: any): void {
139
- this.info(`[FluxStack] ${message}`, meta)
140
- }
141
- }
142
-
143
- // Export singleton instance
144
- export const logger = FluxStackLogger.getInstance()
145
-
146
- // Export convenience functions
147
- export const log = {
148
- debug: (message: string, meta?: any) => logger.debug(message, meta),
149
- info: (message: string, meta?: any) => logger.info(message, meta),
150
- warn: (message: string, meta?: any) => logger.warn(message, meta),
151
- error: (message: string, meta?: any) => logger.error(message, meta),
152
- request: (method: string, path: string, status?: number, duration?: number) =>
153
- logger.request(method, path, status, duration),
154
- plugin: (pluginName: string, message: string, meta?: any) =>
155
- logger.plugin(pluginName, message, meta),
156
- framework: (message: string, meta?: any) =>
157
- logger.framework(message, meta),
158
- child: (context: any) => logger.child(context),
159
- time: (label: string) => logger.time(label),
160
- timeEnd: (label: string) => logger.timeEnd(label)
161
- }
@@ -1,106 +0,0 @@
1
- /**
2
- * FluxStack Logger
3
- * Environment-aware logging system
4
- */
5
-
6
- type LogLevel = 'debug' | 'info' | 'warn' | 'error'
7
-
8
- class Logger {
9
- private static instance: Logger | null = null
10
- private logLevel: LogLevel
11
-
12
- private constructor() {
13
- this.logLevel = (process.env.LOG_LEVEL as LogLevel) || 'info'
14
- }
15
-
16
- static getInstance(): Logger {
17
- if (Logger.instance === null) {
18
- Logger.instance = new Logger()
19
- }
20
- return Logger.instance
21
- }
22
-
23
- private shouldLog(level: LogLevel): boolean {
24
- const levels: Record<LogLevel, number> = {
25
- debug: 0,
26
- info: 1,
27
- warn: 2,
28
- error: 3
29
- }
30
-
31
- return levels[level] >= levels[this.logLevel]
32
- }
33
-
34
- private formatMessage(level: LogLevel, message: string, meta?: any): string {
35
- const timestamp = new Date().toISOString()
36
- const levelStr = level.toUpperCase().padEnd(5)
37
-
38
- let formatted = `[${timestamp}] ${levelStr} ${message}`
39
-
40
- if (meta && typeof meta === 'object') {
41
- formatted += ` ${JSON.stringify(meta)}`
42
- } else if (meta !== undefined) {
43
- formatted += ` ${meta}`
44
- }
45
-
46
- return formatted
47
- }
48
-
49
- debug(message: string, meta?: any): void {
50
- if (this.shouldLog('debug')) {
51
- console.debug(this.formatMessage('debug', message, meta))
52
- }
53
- }
54
-
55
- info(message: string, meta?: any): void {
56
- if (this.shouldLog('info')) {
57
- console.info(this.formatMessage('info', message, meta))
58
- }
59
- }
60
-
61
- warn(message: string, meta?: any): void {
62
- if (this.shouldLog('warn')) {
63
- console.warn(this.formatMessage('warn', message, meta))
64
- }
65
- }
66
-
67
- error(message: string, meta?: any): void {
68
- if (this.shouldLog('error')) {
69
- console.error(this.formatMessage('error', message, meta))
70
- }
71
- }
72
-
73
- // HTTP request logging
74
- request(method: string, path: string, status?: number, duration?: number): void {
75
- const statusStr = status ? ` ${status}` : ''
76
- const durationStr = duration ? ` (${duration}ms)` : ''
77
- this.info(`${method} ${path}${statusStr}${durationStr}`)
78
- }
79
-
80
- // Plugin logging
81
- plugin(pluginName: string, message: string, meta?: any): void {
82
- this.debug(`[${pluginName}] ${message}`, meta)
83
- }
84
-
85
- // Framework logging
86
- framework(message: string, meta?: any): void {
87
- this.info(`[FluxStack] ${message}`, meta)
88
- }
89
- }
90
-
91
- // Export singleton instance
92
- export const logger = Logger.getInstance()
93
-
94
- // Export convenience functions
95
- export const log = {
96
- debug: (message: string, meta?: any) => logger.debug(message, meta),
97
- info: (message: string, meta?: any) => logger.info(message, meta),
98
- warn: (message: string, meta?: any) => logger.warn(message, meta),
99
- error: (message: string, meta?: any) => logger.error(message, meta),
100
- request: (method: string, path: string, status?: number, duration?: number) =>
101
- logger.request(method, path, status, duration),
102
- plugin: (pluginName: string, message: string, meta?: any) =>
103
- logger.plugin(pluginName, message, meta),
104
- framework: (message: string, meta?: any) =>
105
- logger.framework(message, meta)
106
- }
@@ -1,212 +0,0 @@
1
- export interface Metric {
2
- name: string
3
- type: 'counter' | 'gauge' | 'histogram'
4
- help: string
5
- labels?: string[]
6
- value?: number
7
- values?: number[]
8
- }
9
-
10
- export interface Counter extends Metric {
11
- type: 'counter'
12
- inc(value?: number, labels?: Record<string, string>): void
13
- }
14
-
15
- export interface Gauge extends Metric {
16
- type: 'gauge'
17
- set(value: number, labels?: Record<string, string>): void
18
- inc(value?: number, labels?: Record<string, string>): void
19
- dec(value?: number, labels?: Record<string, string>): void
20
- }
21
-
22
- export interface Histogram extends Metric {
23
- type: 'histogram'
24
- observe(value: number, labels?: Record<string, string>): void
25
- buckets: number[]
26
- }
27
-
28
- export interface SystemMetrics {
29
- memoryUsage: {
30
- rss: number
31
- heapTotal: number
32
- heapUsed: number
33
- external: number
34
- }
35
- cpuUsage: {
36
- user: number
37
- system: number
38
- }
39
- eventLoopLag: number
40
- uptime: number
41
- }
42
-
43
- export interface HttpMetrics {
44
- requestsTotal: number
45
- requestDuration: number[]
46
- requestSize: number[]
47
- responseSize: number[]
48
- errorRate: number
49
- }
50
-
51
- export class MetricsCollector {
52
- private metrics: Map<string, Metric> = new Map()
53
- private httpMetrics: HttpMetrics = {
54
- requestsTotal: 0,
55
- requestDuration: [],
56
- requestSize: [],
57
- responseSize: [],
58
- errorRate: 0
59
- }
60
-
61
- // Create metrics
62
- createCounter(name: string, help: string, labels?: string[]): Counter {
63
- const counter: Counter = {
64
- name,
65
- type: 'counter',
66
- help,
67
- labels,
68
- value: 0,
69
- inc: (value = 1, _labels) => {
70
- counter.value = (counter.value || 0) + value
71
- }
72
- }
73
-
74
- this.metrics.set(name, counter)
75
- return counter
76
- }
77
-
78
- createGauge(name: string, help: string, labels?: string[]): Gauge {
79
- const gauge: Gauge = {
80
- name,
81
- type: 'gauge',
82
- help,
83
- labels,
84
- value: 0,
85
- set: (value, _labels) => {
86
- gauge.value = value
87
- },
88
- inc: (value = 1, _labels) => {
89
- gauge.value = (gauge.value || 0) + value
90
- },
91
- dec: (value = 1, _labels) => {
92
- gauge.value = (gauge.value || 0) - value
93
- }
94
- }
95
-
96
- this.metrics.set(name, gauge)
97
- return gauge
98
- }
99
-
100
- createHistogram(name: string, help: string, buckets: number[] = [0.1, 0.5, 1, 2.5, 5, 10]): Histogram {
101
- const histogram: Histogram = {
102
- name,
103
- type: 'histogram',
104
- help,
105
- buckets,
106
- values: [],
107
- observe: (value, _labels) => {
108
- histogram.values = histogram.values || []
109
- histogram.values.push(value)
110
- }
111
- }
112
-
113
- this.metrics.set(name, histogram)
114
- return histogram
115
- }
116
-
117
- // HTTP metrics
118
- recordHttpRequest(_method: string, _path: string, statusCode: number, duration: number, requestSize?: number, responseSize?: number): void {
119
- this.httpMetrics.requestsTotal++
120
- this.httpMetrics.requestDuration.push(duration)
121
-
122
- if (requestSize) {
123
- this.httpMetrics.requestSize.push(requestSize)
124
- }
125
-
126
- if (responseSize) {
127
- this.httpMetrics.responseSize.push(responseSize)
128
- }
129
-
130
- if (statusCode >= 400) {
131
- this.httpMetrics.errorRate = this.calculateErrorRate()
132
- }
133
- }
134
-
135
- // System metrics
136
- getSystemMetrics(): SystemMetrics {
137
- const memUsage = process.memoryUsage()
138
- const cpuUsage = process.cpuUsage()
139
-
140
- return {
141
- memoryUsage: {
142
- rss: memUsage.rss,
143
- heapTotal: memUsage.heapTotal,
144
- heapUsed: memUsage.heapUsed,
145
- external: memUsage.external
146
- },
147
- cpuUsage: {
148
- user: cpuUsage.user,
149
- system: cpuUsage.system
150
- },
151
- eventLoopLag: this.measureEventLoopLag(),
152
- uptime: process.uptime()
153
- }
154
- }
155
-
156
- // Get all metrics
157
- getAllMetrics(): Map<string, Metric> {
158
- return new Map(this.metrics)
159
- }
160
-
161
- getHttpMetrics(): HttpMetrics {
162
- return { ...this.httpMetrics }
163
- }
164
-
165
- // Export metrics in Prometheus format
166
- exportPrometheus(): string {
167
- let output = ''
168
-
169
- for (const metric of this.metrics.values()) {
170
- output += `# HELP ${metric.name} ${metric.help}\n`
171
- output += `# TYPE ${metric.name} ${metric.type}\n`
172
-
173
- if (metric.type === 'counter' || metric.type === 'gauge') {
174
- output += `${metric.name} ${metric.value || 0}\n`
175
- } else if (metric.type === 'histogram' && metric.values) {
176
- const values = metric.values.sort((a, b) => a - b)
177
- const buckets = (metric as Histogram).buckets
178
-
179
- for (const bucket of buckets) {
180
- const count = values.filter(v => v <= bucket).length
181
- output += `${metric.name}_bucket{le="${bucket}"} ${count}\n`
182
- }
183
-
184
- output += `${metric.name}_bucket{le="+Inf"} ${values.length}\n`
185
- output += `${metric.name}_count ${values.length}\n`
186
- output += `${metric.name}_sum ${values.reduce((sum, v) => sum + v, 0)}\n`
187
- }
188
-
189
- output += '\n'
190
- }
191
-
192
- return output
193
- }
194
-
195
- private calculateErrorRate(): number {
196
- const totalRequests = this.httpMetrics.requestsTotal
197
- if (totalRequests === 0) return 0
198
-
199
- // This is a simplified calculation - in a real implementation,
200
- // you'd track error counts separately
201
- return 0 // Placeholder
202
- }
203
-
204
- private measureEventLoopLag(): number {
205
- const start = process.hrtime.bigint()
206
- setImmediate(() => {
207
- const lag = Number(process.hrtime.bigint() - start) / 1e6 // Convert to milliseconds
208
- return lag
209
- })
210
- return 0 // Placeholder - actual implementation would be more complex
211
- }
212
- }
package/tsconfig.json DELETED
@@ -1,51 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Enable latest features
4
- "lib": ["ESNext", "DOM", "DOM.Iterable"],
5
- "target": "ES2022",
6
- "module": "ES2022",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
- "types": ["node"],
11
- "typeRoots": ["./types", "./node_modules/@types"],
12
-
13
- // Bundler mode
14
- "moduleResolution": "bundler",
15
- "allowImportingTsExtensions": true,
16
- "verbatimModuleSyntax": true,
17
- "noEmit": true,
18
- "downlevelIteration": true,
19
-
20
- // Path mapping (alias support)
21
- "baseUrl": ".",
22
- "paths": {
23
- "@/*": ["./*"],
24
- "@/core/*": ["./core/*"],
25
- "@/app/*": ["./app/*"],
26
- "@/config/*": ["./config/*"],
27
- "@/shared/*": ["./app/shared/*"]
28
- },
29
-
30
- // Best practices
31
- "strict": false,
32
- "skipLibCheck": true,
33
- "noFallthroughCasesInSwitch": true,
34
- "noImplicitAny": false,
35
- "strictNullChecks": false,
36
- "strictFunctionTypes": false,
37
- "noImplicitReturns": false,
38
- "noImplicitThis": false,
39
-
40
- // Some stricter flags (disabled by default)
41
- "noUnusedLocals": false,
42
- "noUnusedParameters": false,
43
- "noPropertyAccessFromIndexSignature": false
44
- },
45
- "exclude": [
46
- "examples/**/*",
47
- "**/*.test.ts",
48
- "**/__tests__/**/*",
49
- "run-env-tests.ts"
50
- ]
51
- }
package/vite.config.ts DELETED
@@ -1,42 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
- import tailwindcss from '@tailwindcss/vite'
4
- import { resolve } from 'path'
5
- import { fileURLToPath, URL } from 'node:url'
6
-
7
- const __dirname = fileURLToPath(new URL('.', import.meta.url))
8
-
9
- // https://vite.dev/config/
10
- export default defineConfig({
11
- plugins: [react(), tailwindcss()],
12
- root: 'app/client',
13
- server: {
14
- port: 5173,
15
- host: true,
16
- proxy: {
17
- '/api': {
18
- target: 'http://localhost:3000',
19
- changeOrigin: true,
20
- secure: false,
21
- }
22
- }
23
- },
24
- build: {
25
- outDir: '../../dist/client'
26
- },
27
- resolve: {
28
- alias: {
29
- '@': resolve(__dirname, './app/client/src'),
30
- '@/core': resolve(__dirname, './core'),
31
- '@/app': resolve(__dirname, './app'),
32
- '@/config': resolve(__dirname, './config'),
33
- '@/shared': resolve(__dirname, './app/shared'),
34
- '@/components': resolve(__dirname, './app/client/src/components'),
35
- '@/utils': resolve(__dirname, './app/client/src/utils'),
36
- '@/hooks': resolve(__dirname, './app/client/src/hooks'),
37
- '@/assets': resolve(__dirname, './app/client/src/assets'),
38
- '@/lib': resolve(__dirname, './app/client/src/lib'),
39
- '@/types': resolve(__dirname, './app/client/src/types')
40
- }
41
- }
42
- })