frontend-hamroun 1.2.4 → 1.2.6
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.
- package/dist/backend/auth.js +2 -1
- package/dist/backend/model.js +2 -0
- package/dist/context.d.ts +3 -4
- package/dist/context.js +6 -8
- package/dist/frontend-hamroun.es.js +989 -1276
- package/dist/frontend-hamroun.umd.js +66 -2
- package/dist/index.d.ts +58 -14
- package/dist/index.js +26 -13
- package/package.json +1 -1
- package/src/backend/auth.ts +2 -1
- package/src/backend/model.ts +2 -0
- package/src/context.ts +11 -14
- package/src/index.ts +72 -43
- package/src/shims.d.ts +20 -0
- package/templates/basic-app/src/App.tsx +53 -1
- package/templates/basic-app/src/main.tsx +18 -1
- package/templates/basic-app/vite.config.ts +9 -36
- package/dist/frontend-hamroun.es.js.map +0 -1
- package/dist/frontend-hamroun.umd.js.map +0 -1
@@ -1,8 +1,9 @@
|
|
1
|
-
import { useState, useEffect } from 'frontend-hamroun';
|
1
|
+
import { useState, useEffect, useContext } from 'frontend-hamroun';
|
2
2
|
import { Header } from './components/Header';
|
3
3
|
import { Counter } from './components/Counter';
|
4
4
|
import { ApiClient } from './api.js';
|
5
5
|
import { TodoList } from './components/TodoList.js';
|
6
|
+
import { AppContext } from './main';
|
6
7
|
|
7
8
|
interface AppProps {
|
8
9
|
api: ApiClient;
|
@@ -12,6 +13,8 @@ export function App({ api }: AppProps) {
|
|
12
13
|
const [todos, setTodos] = useState([]);
|
13
14
|
const [isLoading, setIsLoading] = useState(true);
|
14
15
|
const [error, setError] = useState<string | null>(null);
|
16
|
+
const [count, setCount] = useState(0);
|
17
|
+
const { theme } = useContext(AppContext);
|
15
18
|
|
16
19
|
useEffect(() => {
|
17
20
|
// Fetch data when component mounts
|
@@ -59,6 +62,55 @@ export function App({ api }: AppProps) {
|
|
59
62
|
)}
|
60
63
|
</div>
|
61
64
|
</div>
|
65
|
+
|
66
|
+
<div style={{ fontFamily: 'Arial, sans-serif', maxWidth: '600px', margin: '0 auto', padding: '2rem' }}>
|
67
|
+
<h1 style={{ color: '#333', textAlign: 'center' }}>Frontend Hamroun App</h1>
|
68
|
+
<p style={{ textAlign: 'center' }}>
|
69
|
+
Current theme: <strong>{theme}</strong>
|
70
|
+
</p>
|
71
|
+
<div style={{
|
72
|
+
display: 'flex',
|
73
|
+
flexDirection: 'column',
|
74
|
+
alignItems: 'center',
|
75
|
+
marginTop: '2rem',
|
76
|
+
padding: '1rem',
|
77
|
+
border: '1px solid #ccc',
|
78
|
+
borderRadius: '8px',
|
79
|
+
backgroundColor: theme === 'dark' ? '#333' : '#fff',
|
80
|
+
color: theme === 'dark' ? '#fff' : '#333'
|
81
|
+
}}>
|
82
|
+
<h2>Counter Example</h2>
|
83
|
+
<p>Count: {count}</p>
|
84
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
85
|
+
<button
|
86
|
+
onClick={() => setCount(count - 1)}
|
87
|
+
style={{
|
88
|
+
padding: '8px 16px',
|
89
|
+
background: '#ff4d4d',
|
90
|
+
color: 'white',
|
91
|
+
border: 'none',
|
92
|
+
borderRadius: '4px',
|
93
|
+
cursor: 'pointer'
|
94
|
+
}}
|
95
|
+
>
|
96
|
+
Decrement
|
97
|
+
</button>
|
98
|
+
<button
|
99
|
+
onClick={() => setCount(count + 1)}
|
100
|
+
style={{
|
101
|
+
padding: '8px 16px',
|
102
|
+
background: '#4d79ff',
|
103
|
+
color: 'white',
|
104
|
+
border: 'none',
|
105
|
+
borderRadius: '4px',
|
106
|
+
cursor: 'pointer'
|
107
|
+
}}
|
108
|
+
>
|
109
|
+
Increment
|
110
|
+
</button>
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
</div>
|
62
114
|
</main>
|
63
115
|
</div>
|
64
116
|
);
|
@@ -141,4 +141,21 @@ function ContextConsumer() {
|
|
141
141
|
);
|
142
142
|
}
|
143
143
|
|
144
|
-
render
|
144
|
+
import { render, createContext } from 'frontend-hamroun';
|
145
|
+
import { App } from './App';
|
146
|
+
|
147
|
+
// Create an example context
|
148
|
+
export const AppContext = createContext({ theme: 'light' });
|
149
|
+
|
150
|
+
document.addEventListener('DOMContentLoaded', () => {
|
151
|
+
const rootElement = document.getElementById('app');
|
152
|
+
if (rootElement) {
|
153
|
+
render(
|
154
|
+
<AppContext.Provider value={{ theme: 'light' }}>
|
155
|
+
<App />
|
156
|
+
</AppContext.Provider>,
|
157
|
+
rootElement
|
158
|
+
);
|
159
|
+
console.log('App rendered successfully');
|
160
|
+
}
|
161
|
+
});
|
@@ -10,7 +10,7 @@ export default defineConfig({
|
|
10
10
|
outDir: 'dist',
|
11
11
|
emptyOutDir: true,
|
12
12
|
rollupOptions: {
|
13
|
-
// Mark
|
13
|
+
// Mark server dependencies as external
|
14
14
|
external: [
|
15
15
|
'mock-aws-s3',
|
16
16
|
'aws-sdk',
|
@@ -19,8 +19,6 @@ export default defineConfig({
|
|
19
19
|
'jest-mock',
|
20
20
|
'@testing-library/react',
|
21
21
|
'@testing-library/jest-dom',
|
22
|
-
'@mswjs/interceptors',
|
23
|
-
'node-pre-gyp',
|
24
22
|
'bcrypt',
|
25
23
|
'jsonwebtoken',
|
26
24
|
'mongoose',
|
@@ -37,50 +35,25 @@ export default defineConfig({
|
|
37
35
|
open: true
|
38
36
|
},
|
39
37
|
optimizeDeps: {
|
38
|
+
// Prevent Vite from optimizing Node.js modules
|
39
|
+
exclude: ['bcrypt', 'jsonwebtoken', 'mongoose', 'express', 'compression', 'helmet', 'morgan'],
|
40
40
|
esbuildOptions: {
|
41
|
-
// Node.js global to browser globalThis
|
42
41
|
define: {
|
43
42
|
global: 'globalThis'
|
44
|
-
}
|
45
|
-
|
46
|
-
plugins: [
|
47
|
-
{
|
48
|
-
name: 'node-modules-polyfill',
|
49
|
-
setup(build) {
|
50
|
-
// Exclude node:* imports and html files
|
51
|
-
build.onResolve({ filter: /^node:/ }, () => {
|
52
|
-
return { external: true };
|
53
|
-
});
|
54
|
-
build.onResolve({ filter: /\.html$/ }, () => {
|
55
|
-
return { external: true };
|
56
|
-
});
|
57
|
-
}
|
58
|
-
}
|
59
|
-
]
|
60
|
-
},
|
61
|
-
// Exclude problematic dependencies from optimization
|
62
|
-
exclude: [
|
63
|
-
'mock-aws-s3',
|
64
|
-
'aws-sdk',
|
65
|
-
'nock',
|
66
|
-
'@mswjs/interceptors',
|
67
|
-
'node-pre-gyp',
|
68
|
-
'bcrypt'
|
69
|
-
]
|
43
|
+
}
|
44
|
+
}
|
70
45
|
},
|
71
46
|
plugins: [
|
72
|
-
// Add node polyfills for browser environment
|
73
47
|
nodePolyfills({
|
74
|
-
// Whether to polyfill `node:` protocol imports
|
75
48
|
protocolImports: true,
|
76
49
|
}),
|
77
50
|
],
|
78
51
|
resolve: {
|
79
|
-
// Add node compatibility
|
80
52
|
alias: {
|
81
|
-
//
|
82
|
-
'
|
83
|
-
'
|
53
|
+
// Remove any Node.js specific imports that might cause issues
|
54
|
+
'bcrypt': 'frontend-hamroun',
|
55
|
+
'jsonwebtoken': 'frontend-hamroun',
|
56
|
+
'mongoose': 'frontend-hamroun'
|
84
57
|
}
|
85
58
|
}
|
86
59
|
});
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"frontend-hamroun.es.js","sources":["../src/jsx-runtime/jsx-runtime.ts","../src/jsx-runtime/index.ts","../src/jsx-runtime.ts","../src/component.ts","../src/batch.ts","../src/hooks.ts","../src/renderer.ts","../src/server-renderer.ts","../src/backend/database.ts","../src/backend/server.ts","../src/backend/router.ts","../src/backend/api-utils.ts","../__vite-browser-external","../src/backend/auth.ts","../src/backend/model.ts","../src/index.ts"],"sourcesContent":["import { diff } from '../vdom';\r\n\r\n// Create a safe global object reference that works in both browser and Node\r\nconst globalObj: any = typeof window !== 'undefined' ? window : \r\n typeof global !== 'undefined' ? global : {};\r\n\r\nexport function jsx(type: string | Function, props: any, key?: string): any {\r\n return {\r\n type,\r\n props: props || {},\r\n key\r\n };\r\n}\r\n\r\nexport function jsxs(type: string | Function, props: any, key?: string): any {\r\n return jsx(type, props, key);\r\n}\r\n\r\nexport function createElement(vnode: any): HTMLElement | Text {\r\n if (typeof vnode === 'string' || typeof vnode === 'number') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n if (typeof vnode.type === 'function') {\r\n const result = vnode.type(vnode.props);\r\n return createElement(result);\r\n }\r\n\r\n const element = document.createElement(vnode.type);\r\n \r\n Object.entries(vnode.props || {}).forEach(([name, value]: [string, any]) => {\r\n if (name === 'children') {\r\n const children = Array.isArray(value) ? value : [value];\r\n children.forEach((child: any) => {\r\n if (child != null) {\r\n const childElement = createElement(child);\r\n // Generate stats for testing\r\n if (process.env.NODE_ENV === 'test' && typeof window !== 'undefined') {\r\n // Create stats tracking\r\n if (!globalObj.__renderStats) {\r\n globalObj.__renderStats = {\r\n elementsCreated: 0,\r\n textNodesCreated: 0,\r\n eventsAttached: 0,\r\n renderTime: 0\r\n };\r\n \r\n // Write stats to file when tests complete\r\n if (typeof afterAll === 'function') {\r\n afterAll(() => {\r\n try {\r\n const fs = require('fs');\r\n const path = require('path');\r\n const statsPath = path.resolve(process.cwd(), 'jsx-runtime-stats.json');\r\n fs.writeFileSync(statsPath, JSON.stringify(globalObj.__renderStats, null, 2));\r\n console.log(`JSX runtime stats written to ${statsPath}`);\r\n } catch (error) {\r\n console.error('Failed to write stats file:', error);\r\n }\r\n });\r\n }\r\n }\r\n \r\n // Increment stats based on element type\r\n if (childElement instanceof Text) {\r\n globalObj.__renderStats.textNodesCreated++;\r\n } else {\r\n globalObj.__renderStats.elementsCreated++;\r\n }\r\n }\r\n \r\n element.appendChild(childElement);\r\n }\r\n });\r\n } else if (name.startsWith('on')) {\r\n const eventName = name.toLowerCase().substring(2);\r\n element.addEventListener(eventName, value);\r\n \r\n // Track event attachment in stats\r\n if (process.env.NODE_ENV === 'test' && typeof window !== 'undefined' && globalObj.__renderStats) {\r\n globalObj.__renderStats.eventsAttached++;\r\n }\r\n } else if (name === 'className') {\r\n // Handle className specially by setting it as the class attribute\r\n element.setAttribute('class', value);\r\n } else if (name === 'style' && typeof value === 'object') {\r\n // Handle style objects by merging them into element.style\r\n Object.entries(value).forEach(([styleProp, styleValue]) => {\r\n element.style[styleProp as any] = String(styleValue);\r\n });\r\n } else {\r\n element.setAttribute(name, value);\r\n }\r\n });\r\n\r\n return element;\r\n}\r\n\r\nexport const Fragment = Symbol('Fragment');\r\n","import { jsx, jsxs, createElement, Fragment } from './jsx-runtime';\r\n\r\nexport {\r\n jsx,\r\n jsxs,\r\n createElement,\r\n Fragment\r\n};\r\n\r\n// For global access in browsers\r\nif (typeof window !== 'undefined') {\r\n // TypeScript safe way to add properties to window\r\n (window as any).jsx = jsx;\r\n (window as any).jsxs = jsxs;\r\n (window as any).Fragment = Fragment;\r\n}\r\n\r\n// Default export for module usage\r\nexport default {\r\n jsx,\r\n jsxs,\r\n createElement,\r\n Fragment\r\n};\r\n","import type { Component } from './component';\r\n\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any, p0: string): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\n// Check if we're in a browser environment\r\nconst isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Create mock DOM elements when in Node environment\r\n if (!isBrowser) {\r\n // Return mock node objects in Node.js environment\r\n if (vnode == null) {\r\n return { nodeType: 3, textContent: '' } as any;\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return { nodeType: 3, textContent: '' } as any;\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return { nodeType: 3, textContent: String(vnode) } as any;\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = { nodeType: 11, childNodes: [] } as any;\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.childNodes.push(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return { nodeType: 3, textContent: '' } as any;\r\n }\r\n }\r\n\r\n // Mock element creation\r\n const element = { \r\n nodeType: 1, \r\n tagName: type, \r\n attributes: {}, \r\n style: {}, \r\n childNodes: [],\r\n setAttribute: function(key: string, value: string) {\r\n this.attributes[key] = value;\r\n },\r\n appendChild: function(child: any) {\r\n this.childNodes.push(child);\r\n }\r\n } as any;\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n // Mock event handlers\r\n const eventName = key.toLowerCase().slice(2);\r\n if (!element.__events) {\r\n element.__events = {};\r\n }\r\n element.__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return { nodeType: 3, textContent: String(vnode) } as any;\r\n }\r\n \r\n // Browser environment implementation\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime';\r\n\r\nexport class Component {\r\n state: any = {};\r\n props: any;\r\n element: HTMLElement | null = null;\r\n private _mounted: boolean = false;\r\n\r\n constructor(props: any = {}) {\r\n this.props = props;\r\n }\r\n\r\n componentDidMount() {\r\n // Hook for after component is mounted\r\n }\r\n\r\n async setState(newState: any) {\r\n const prevState = { ...this.state };\r\n this.state = { ...prevState, ...newState };\r\n console.log(`${this.constructor.name} state updated:`, {\r\n prev: prevState,\r\n next: this.state\r\n });\r\n \r\n await Promise.resolve(); // Ensure state is updated before re-render\r\n if (this._mounted) {\r\n await this.update();\r\n } else {\r\n await this.update();\r\n }\r\n }\r\n\r\n private _replayEvents(oldElement: HTMLElement, newElement: HTMLElement) {\r\n const oldEvents = (oldElement as any).__events || {};\r\n Object.entries(oldEvents).forEach(([event, handler]) => {\r\n newElement.addEventListener(event as keyof HTMLElementEventMap, handler as EventListener);\r\n });\r\n (newElement as any).__events = oldEvents;\r\n }\r\n\r\n private _deepCloneWithEvents(node: HTMLElement): HTMLElement {\r\n const clone = node.cloneNode(false) as HTMLElement;\r\n \r\n // Copy events from original element\r\n const events = (node as any).__events || {};\r\n (clone as any).__events = events;\r\n Object.entries(events).forEach(([event, handler]) => {\r\n clone.addEventListener(event as keyof HTMLElementEventMap, handler as EventListener);\r\n });\r\n\r\n // Clone children\r\n Array.from(node.childNodes).forEach(child => {\r\n if (child instanceof HTMLElement) {\r\n clone.appendChild(this._deepCloneWithEvents(child));\r\n } else {\r\n clone.appendChild(child.cloneNode(true));\r\n }\r\n });\r\n\r\n return clone;\r\n }\r\n\r\n async update() {\r\n const vdom = this.render();\r\n if (!vdom) return document.createTextNode('');\r\n \r\n const rendered = await createElement(vdom);\r\n if (rendered instanceof HTMLElement) {\r\n return this._updateElement(rendered);\r\n }\r\n \r\n const wrapper = document.createElement('div');\r\n wrapper.appendChild(rendered);\r\n return this._updateElement(wrapper);\r\n }\r\n\r\n private async _updateElement(rendered: HTMLElement) {\r\n const newElement = this._deepCloneWithEvents(rendered);\r\n (newElement as any).__instance = this;\r\n \r\n if (!this.element) {\r\n this.element = newElement;\r\n if (!this._mounted) {\r\n this._mounted = true;\r\n queueMicrotask(() => this.componentDidMount());\r\n }\r\n } else if (this.element.parentNode) {\r\n this.element.parentNode.replaceChild(newElement, this.element);\r\n this.element = newElement;\r\n }\r\n \r\n return this.element;\r\n }\r\n\r\n render(): any {\r\n throw new Error('Component must implement render() method');\r\n }\r\n}\r\n","export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { createElement } from './jsx-runtime';\r\nimport { batchUpdates, isBatching } from './batch';\r\nimport { diff } from './vdom';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","import { createElement } from './jsx-runtime';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks';\r\nimport { batchUpdates } from './batch';\r\n\r\n// Track hydration state\r\nlet isHydrating = false;\r\n\r\n/**\r\n * Hydrates a server-rendered component\r\n * @param element The element to hydrate\r\n * @param container The container element that contains server-rendered HTML\r\n */\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\n/**\r\n * Renders a component to the DOM\r\n * @param element The element to render\r\n * @param container The container to render into\r\n */\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id || 'unnamed-container');\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n // Don't clear container if we're hydrating\r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n \r\n // When hydrating, we should match and update existing nodes\r\n // rather than appending new ones\r\n if (isHydrating && container.firstChild) {\r\n // During hydration, we assume the structure matches\r\n // and just attach event handlers without replacing DOM\r\n console.log('Hydrating existing DOM');\r\n } else {\r\n container.appendChild(domNode);\r\n }\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { prepareRender, finishRender, setRenderCallback } from './hooks';\r\n\r\n/**\r\n * Renders a component to a string\r\n */\r\nexport async function renderToString(element: any): Promise<string> {\r\n // Setup render context\r\n const rendererId = prepareRender();\r\n setRenderCallback(() => {}, element, null as any);\r\n \r\n try {\r\n if (element == null) return '';\r\n \r\n if (typeof element === 'boolean') return '';\r\n \r\n if (typeof element === 'number' || typeof element === 'string') {\r\n return escapeHtml(String(element));\r\n }\r\n\r\n if (Array.isArray(element)) {\r\n const children = await Promise.all(element.map(renderToString));\r\n return children.join('');\r\n }\r\n\r\n if ('type' in element && element.props !== undefined) {\r\n const { type, props } = element;\r\n\r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n // Prepare new render context for the component\r\n prepareRender();\r\n const result = await type(props || {});\r\n const html = await renderToString(result);\r\n finishRender();\r\n return html;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return '';\r\n }\r\n }\r\n\r\n // Handle Fragment special case\r\n if (type === Symbol.for('react.fragment') || type.name === 'Fragment') {\r\n if (props.children) {\r\n const children = Array.isArray(props.children) ? props.children : [props.children];\r\n const renderedChildren = await Promise.all(children.map(renderToString));\r\n return renderedChildren.join('');\r\n }\r\n return '';\r\n }\r\n\r\n // Handle regular elements\r\n let html = `<${type}`;\r\n\r\n // Add attributes, skipping internal ones like 'key'\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children' || key === 'key') continue;\r\n if (key === 'className') {\r\n html += ` class=\"${escapeHtml(String(value))}\"`;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n html += ` style=\"${stringifyStyle(value || {})}\"`;\r\n } else if (!key.startsWith('on')) {\r\n html += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n }\r\n }\r\n\r\n // Handle self-closing tags\r\n const voidElements = new Set([\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ]);\r\n \r\n if (voidElements.has(type)) {\r\n return html + '/>';\r\n }\r\n\r\n html += '>';\r\n\r\n // Add children\r\n if (props?.children) {\r\n const children = Array.isArray(props.children) ? props.children : [props.children];\r\n for (const child of children) {\r\n html += await renderToString(child);\r\n }\r\n }\r\n\r\n return html + `</${type}>`;\r\n }\r\n\r\n return escapeHtml(String(element));\r\n } finally {\r\n finishRender();\r\n }\r\n}\r\n\r\nfunction escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n\r\nfunction stringifyStyle(style: Record<string, any>): string {\r\n return Object.entries(style)\r\n .map(([key, value]) => `${hyphenate(key)}:${value}`)\r\n .join(';');\r\n}\r\n\r\nfunction hyphenate(str: string): string {\r\n return str.replace(/[A-Z]/g, match => '-' + match.toLowerCase());\r\n}\r\n","import mongoose from 'mongoose';\r\nimport { DatabaseOptions } from './types';\r\n\r\n/**\r\n * Database connector for MongoDB using Mongoose\r\n */\r\nexport class DatabaseConnector {\r\n private options: DatabaseOptions;\r\n private connection: mongoose.Connection | null = null;\r\n private _connected = false; // Renamed from isConnected to _connected\r\n\r\n constructor(options: DatabaseOptions) {\r\n this.options = {\r\n retryAttempts: 3,\r\n retryDelay: 1000,\r\n connectionTimeout: 10000,\r\n autoIndex: true,\r\n ...options\r\n };\r\n }\r\n\r\n /**\r\n * Connect to the database\r\n */\r\n async connect(): Promise<mongoose.Connection> {\r\n try {\r\n if (this._connected && this.connection) {\r\n return this.connection;\r\n }\r\n\r\n // Set Mongoose options\r\n mongoose.set('strictQuery', true);\r\n \r\n // Connect with retry logic\r\n let attempts = 0;\r\n while (attempts < (this.options.retryAttempts || 3)) {\r\n try {\r\n await mongoose.connect(this.options.uri, {\r\n dbName: this.options.name,\r\n connectTimeoutMS: this.options.connectionTimeout,\r\n autoIndex: this.options.autoIndex,\r\n ...this.options.options\r\n });\r\n break;\r\n } catch (error) {\r\n attempts++;\r\n if (attempts >= (this.options.retryAttempts || 3)) {\r\n throw error;\r\n }\r\n console.log(`Connection attempt ${attempts} failed. Retrying in ${this.options.retryDelay}ms...`);\r\n await new Promise(resolve => setTimeout(resolve, this.options.retryDelay));\r\n }\r\n }\r\n\r\n this.connection = mongoose.connection;\r\n this._connected = true;\r\n\r\n // Log successful connection\r\n console.log(`Connected to MongoDB at ${this.options.uri}/${this.options.name}`);\r\n \r\n // Handle connection events\r\n this.connection.on('error', (err) => {\r\n console.error('MongoDB connection error:', err);\r\n this._connected = false;\r\n });\r\n\r\n this.connection.on('disconnected', () => {\r\n console.log('MongoDB disconnected');\r\n this._connected = false;\r\n });\r\n\r\n return this.connection;\r\n } catch (error) {\r\n console.error('Failed to connect to MongoDB:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect from the database\r\n */\r\n async disconnect(): Promise<void> {\r\n if (this.connection) {\r\n await mongoose.disconnect();\r\n this._connected = false;\r\n this.connection = null;\r\n console.log('Disconnected from MongoDB');\r\n }\r\n }\r\n\r\n /**\r\n * Check if connected to the database\r\n */\r\n isConnected(): boolean {\r\n return this._connected;\r\n }\r\n\r\n /**\r\n * Get the mongoose connection\r\n */\r\n getConnection(): mongoose.Connection | null {\r\n return this.connection;\r\n }\r\n}","import express, { Express, Request, Response, NextFunction } from 'express';\r\nimport path from 'path';\r\nimport compression from 'compression';\r\nimport helmet from 'helmet';\r\nimport morgan from 'morgan';\r\nimport { renderToString } from '../server-renderer';\r\nimport { RouterOptions, HamrounServerOptions, DatabaseOptions } from './types';\r\nimport { DatabaseConnector } from './database';\r\nimport fs from 'fs';\r\n\r\n/**\r\n * Creates an Express server configured for Frontend Hamroun applications\r\n * @param options Server configuration options\r\n * @returns Configured Express application\r\n */\r\nexport function createServer(options: HamrounServerOptions = {}): Express {\r\n const app = express();\r\n const {\r\n port = 3000,\r\n staticDir = 'public',\r\n enableCors = true,\r\n apiPrefix = '/api',\r\n ssrEnabled = true,\r\n middlewares = [],\r\n enableCompression = true,\r\n enableHelmet = true,\r\n logFormat = 'dev',\r\n trustProxy = false,\r\n showErrorDetails = process.env.NODE_ENV !== 'production',\r\n } = options;\r\n\r\n // Trust proxy if enabled\r\n if (trustProxy) {\r\n app.set('trust proxy', trustProxy);\r\n }\r\n\r\n // Basic middleware\r\n app.use(express.json());\r\n app.use(express.urlencoded({ extended: true }));\r\n \r\n // Compression middleware\r\n if (enableCompression) {\r\n app.use(compression());\r\n }\r\n \r\n // Security middleware\r\n if (enableHelmet) {\r\n app.use(helmet({\r\n contentSecurityPolicy: options.disableCSP ? false : undefined,\r\n }));\r\n }\r\n \r\n // Request logging\r\n if (logFormat) {\r\n app.use(morgan(logFormat));\r\n }\r\n \r\n // CORS if enabled\r\n if (enableCors) {\r\n app.use((req: Request, res: Response, next: NextFunction) => {\r\n res.header('Access-Control-Allow-Origin', '*');\r\n res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');\r\n res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');\r\n if (req.method === 'OPTIONS') {\r\n return res.sendStatus(200);\r\n }\r\n next();\r\n });\r\n }\r\n\r\n // Apply custom middlewares\r\n middlewares.forEach((middleware: any) => app.use(middleware));\r\n \r\n // Serve static files with appropriate caching\r\n if (staticDir) {\r\n const staticPath = path.resolve(process.cwd(), staticDir);\r\n if (fs.existsSync(staticPath)) {\r\n app.use(express.static(staticPath, {\r\n maxAge: options.staticCacheAge || '1d',\r\n etag: true,\r\n }));\r\n console.log(`📂 Serving static files from: ${staticPath}`);\r\n } else {\r\n console.warn(`⚠️ Static directory not found: ${staticPath}`);\r\n }\r\n }\r\n\r\n // Database connection reference\r\n let dbConnector: DatabaseConnector | null = null;\r\n\r\n // Method to connect to database with better error handling\r\n app.connectToDatabase = async (dbOptions: DatabaseOptions): Promise<DatabaseConnector> => {\r\n try {\r\n if (dbConnector && dbConnector.isConnected()) {\r\n console.log('✅ Using existing database connection');\r\n return dbConnector;\r\n }\r\n \r\n dbConnector = new DatabaseConnector(dbOptions);\r\n await dbConnector.connect();\r\n console.log('✅ Database connected successfully');\r\n \r\n // Add disconnect handler for graceful shutdown\r\n process.on('SIGTERM', async () => {\r\n if (dbConnector && dbConnector.isConnected()) {\r\n await dbConnector.disconnect();\r\n console.log('Database connection closed');\r\n }\r\n });\r\n \r\n return dbConnector;\r\n } catch (error) {\r\n console.error('❌ Failed to connect to database:', error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Store registered routes for better management\r\n const routes: Record<string, any> = {};\r\n const ssrRoutes: Record<string, any> = {};\r\n\r\n // Method to register API routes with better integration of auth middleware\r\n app.registerApi = (routePath: string, router: any, routerOptions: RouterOptions = {}) => {\r\n try {\r\n const { prefix = apiPrefix } = routerOptions;\r\n const fullPath = path.posix.join(prefix, routePath).replace(/\\\\/g, '/');\r\n app.use(fullPath, router);\r\n routes[fullPath] = { router, options: routerOptions };\r\n console.log(`🔌 API registered: ${fullPath}`);\r\n } catch (error) {\r\n console.error(`❌ Failed to register API at ${routePath}:`, error);\r\n }\r\n return app;\r\n };\r\n\r\n // Method to register SSR handler with better error handling\r\n app.registerSSR = (routePath: string, component: any, options: any = {}) => {\r\n if (!ssrEnabled) {\r\n console.log(`⚠️ SSR disabled: skipping registration of ${routePath}`);\r\n return app;\r\n }\r\n \r\n ssrRoutes[routePath] = { component, options };\r\n \r\n app.get(routePath, async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n // Skip SSR if requested via query param\r\n if (req.query.nossr === 'true') {\r\n return next();\r\n }\r\n \r\n // Setup props for the component\r\n const props = {\r\n req, \r\n res,\r\n params: req.params,\r\n query: req.query,\r\n user: (req as any).user,\r\n ...options.props\r\n };\r\n \r\n // Server-side render the component\r\n const html = await renderToString(component(props));\r\n \r\n // Send the full HTML document\r\n res.send(`\r\n <!DOCTYPE html>\r\n <html lang=\"${options.lang || 'en'}\">\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n <title>${options.title || 'Frontend Hamroun App'}</title>\r\n ${options.meta ? options.meta.map((meta: any) => \r\n `<meta ${Object.entries(meta).map(([k, v]) => `${k}=\"${v}\"`).join(' ')}>`)\r\n .join('\\n ') : ''}\r\n ${options.head || ''}\r\n ${options.styles ? `<style>${options.styles}</style>` : ''}\r\n ${options.styleSheets ? options.styleSheets.map((sheet: string) => \r\n `<link rel=\"stylesheet\" href=\"${sheet}\">`).join('\\n ') : ''}\r\n </head>\r\n <body ${options.bodyAttributes || ''}>\r\n <div id=\"${options.rootId || 'root'}\">${html}</div>\r\n <script>\r\n window.__INITIAL_DATA__ = ${JSON.stringify(options.initialData || {})};\r\n </script>\r\n ${options.scripts ? options.scripts.map((script: string) => \r\n `<script src=\"${script}\"></script>`).join('\\n ') : ''}\r\n </body>\r\n </html>\r\n `);\r\n } catch (error) {\r\n console.error('SSR Error:', error);\r\n \r\n // If fallback is enabled, continue to next middleware\r\n if (options.fallback) {\r\n return next();\r\n }\r\n \r\n res.status(500).send('Server rendering error');\r\n }\r\n });\r\n \r\n console.log(`🖥️ SSR registered: ${routePath}`);\r\n return app;\r\n };\r\n\r\n // Global error handler with better formatting\r\n app.use((err: Error, req: Request, res: Response, next: NextFunction) => {\r\n console.error('Server error:', err);\r\n \r\n // Determine status code\r\n const statusCode = (err as any).statusCode || (err as any).status || 500;\r\n \r\n // Format error response based on the request\r\n const isApiRequest = req.path.startsWith(apiPrefix);\r\n \r\n if (isApiRequest) {\r\n // API error response\r\n res.status(statusCode).json({\r\n success: false,\r\n error: showErrorDetails ? err.message : 'Internal Server Error',\r\n stack: showErrorDetails ? err.stack : undefined\r\n });\r\n } else {\r\n // Web error response\r\n res.status(statusCode).send(`\r\n <!DOCTYPE html>\r\n <html>\r\n <head>\r\n <title>Error - ${statusCode}</title>\r\n <style>\r\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\r\n .error { background: #f8d7da; border: 1px solid #f5c6cb; padding: 1rem; border-radius: 4px; }\r\n .stack { background: #f8f9fa; padding: 1rem; border-radius: 4px; overflow: auto; }\r\n </style>\r\n </head>\r\n <body>\r\n <h1>Error ${statusCode}</h1>\r\n <div class=\"error\">${showErrorDetails ? err.message : 'Internal Server Error'}</div>\r\n ${showErrorDetails && err.stack ? `<pre class=\"stack\">${err.stack}</pre>` : ''}\r\n </body>\r\n </html>\r\n `);\r\n }\r\n });\r\n\r\n // 404 handler\r\n app.use((req: Request, res: Response) => {\r\n const isApiRequest = req.path.startsWith(apiPrefix);\r\n \r\n if (isApiRequest) {\r\n res.status(404).json({ success: false, error: 'Not Found' });\r\n } else {\r\n res.status(404).send(`\r\n <!DOCTYPE html>\r\n <html>\r\n <head>\r\n <title>404 - Not Found</title>\r\n <style>\r\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\r\n </style>\r\n </head>\r\n <body>\r\n <h1>404 - Not Found</h1>\r\n <p>The requested resource was not found on this server.</p>\r\n <p><a href=\"/\">Return to homepage</a></p>\r\n </body>\r\n </html>\r\n `);\r\n }\r\n });\r\n\r\n // Start the server with graceful shutdown\r\n app.start = (callback?: () => void) => {\r\n const server = app.listen(port, () => {\r\n console.log(`\r\n🚀 Frontend Hamroun server running at http://localhost:${port}\r\n${Object.keys(routes).length > 0 ? `\\n📡 Registered API Routes:\r\n${Object.keys(routes).map(route => ` ${route}`).join('\\n')}` : ''}\r\n${Object.keys(ssrRoutes).length > 0 ? `\\n🖥️ Registered SSR Routes:\r\n${Object.keys(ssrRoutes).map(route => ` ${route}`).join('\\n')}` : ''}\r\n `);\r\n \r\n if (callback) callback();\r\n });\r\n \r\n // Graceful shutdown\r\n const gracefulShutdown = async (signal: string) => {\r\n console.log(`${signal} signal received: closing HTTP server and cleaning up`);\r\n \r\n server.close(async () => {\r\n console.log('HTTP server closed');\r\n \r\n // Close database connection if it exists\r\n if (dbConnector && dbConnector.isConnected()) {\r\n await dbConnector.disconnect();\r\n console.log('Database connection closed');\r\n }\r\n \r\n process.exit(0);\r\n });\r\n \r\n // Force close after timeout\r\n setTimeout(() => {\r\n console.error('Could not close connections in time, forcefully shutting down');\r\n process.exit(1);\r\n }, 10000);\r\n };\r\n \r\n // Listen for termination signals\r\n process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));\r\n process.on('SIGINT', () => gracefulShutdown('SIGINT'));\r\n \r\n return server;\r\n };\r\n\r\n return app;\r\n}\r\n\r\n// Update the global Express Application interface\r\ndeclare global {\r\n namespace Express {\r\n interface Application {\r\n registerApi: (routePath: string, router: any, options?: RouterOptions) => Application;\r\n registerSSR: (routePath: string, component: any, options?: any) => Application;\r\n start: (callback?: () => void) => any;\r\n connectToDatabase: (dbOptions: DatabaseOptions) => Promise<DatabaseConnector>;\r\n }\r\n }\r\n}","import express, { Router, Request, Response, NextFunction } from 'express';\r\nimport { Model, RouteContext } from './types';\r\n\r\n// Handler types\r\ntype RequestHandler = (context: RouteContext) => Promise<any> | any;\r\ntype ErrorHandler = (error: any, context: RouteContext) => Promise<any> | any;\r\n\r\n// Default error handler with improved formatting and consistent response\r\nconst defaultErrorHandler = (error: any, { res }: RouteContext) => {\r\n console.error('API Error:', error);\r\n const status = error.status || error.statusCode || 500;\r\n const message = error.message || 'Internal server error';\r\n res.status(status).json({ \r\n success: false, \r\n error: message,\r\n stack: process.env.NODE_ENV !== 'production' ? error.stack : undefined\r\n });\r\n};\r\n\r\n/**\r\n * Options for API route creation\r\n */\r\ninterface RouteOptions {\r\n middleware?: ((req: Request, res: Response, next: NextFunction) => void)[];\r\n errorHandler?: ErrorHandler;\r\n}\r\n\r\n/**\r\n * Creates a router for a data model with CRUD endpoints\r\n * @param model The data model\r\n * @param options Router options\r\n */\r\nexport function createModelRouter<T>(\r\n model: Model<T>,\r\n options: RouteOptions = {}\r\n): Router {\r\n const router = express.Router();\r\n const { middleware = [], errorHandler = defaultErrorHandler } = options;\r\n\r\n // Apply middleware\r\n middleware.forEach(mw => router.use(mw));\r\n \r\n // Helper to wrap handlers with error handling\r\n const handleRoute = (handler: RequestHandler) => async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const context: RouteContext = { req, res, next, params: req.params, query: req.query, body: req.body };\r\n return await handler(context);\r\n } catch (error) {\r\n const context: RouteContext = { req, res, next, params: req.params, query: req.query, body: req.body };\r\n return errorHandler(error, context);\r\n }\r\n };\r\n \r\n // GET all items with pagination\r\n router.get('/', handleRoute(async ({ req, res }) => {\r\n const paginationOptions = req.pagination || { page: 1, limit: 10 };\r\n const result = await model.getAll(paginationOptions);\r\n res.json({ \r\n success: true,\r\n ...result\r\n });\r\n }));\r\n \r\n // GET item by ID\r\n router.get('/:id', handleRoute(async ({ params, res }) => {\r\n const item = await model.getById(params.id);\r\n if (!item) {\r\n res.status(404).json({ \r\n success: false,\r\n error: 'Item not found' \r\n });\r\n return;\r\n }\r\n res.json({ \r\n success: true,\r\n data: item \r\n });\r\n }));\r\n \r\n // POST new item\r\n router.post('/', handleRoute(async ({ body, res }) => {\r\n const newItem = await model.create(body);\r\n res.status(201).json({ \r\n success: true,\r\n data: newItem,\r\n message: 'Item created successfully'\r\n });\r\n }));\r\n \r\n // PUT update item\r\n router.put('/:id', handleRoute(async ({ params, body, res }) => {\r\n const updatedItem = await model.update(params.id, body);\r\n if (!updatedItem) {\r\n res.status(404).json({ \r\n success: false,\r\n error: 'Item not found' \r\n });\r\n return;\r\n }\r\n res.json({ \r\n success: true,\r\n data: updatedItem,\r\n message: 'Item updated successfully'\r\n });\r\n }));\r\n \r\n // DELETE item\r\n router.delete('/:id', handleRoute(async ({ params, res }) => {\r\n const success = await model.delete(params.id);\r\n if (!success) {\r\n res.status(404).json({ \r\n success: false,\r\n error: 'Item not found' \r\n });\r\n return;\r\n }\r\n res.json({ \r\n success: true,\r\n message: 'Item deleted successfully'\r\n });\r\n }));\r\n \r\n return router;\r\n}\r\n\r\n/**\r\n * Creates a custom API router\r\n * @param routeConfig Custom route configuration\r\n * @param options Router options\r\n */\r\nexport function createApiRouter(\r\n routeConfig: Record<string, { \r\n method: 'get' | 'post' | 'put' | 'delete' | 'patch',\r\n handler: RequestHandler \r\n }>,\r\n options: RouteOptions = {}\r\n): Router {\r\n const router = express.Router();\r\n const { middleware = [], errorHandler = defaultErrorHandler } = options;\r\n \r\n // Apply middleware\r\n middleware.forEach(mw => router.use(mw));\r\n \r\n // Helper to wrap handlers with error handling\r\n const handleRoute = (handler: RequestHandler) => async (req: Request, res: Response, next: NextFunction) => {\r\n try {\r\n const context: RouteContext = { req, res, next, params: req.params, query: req.query, body: req.body };\r\n \r\n // Check if response is already sent before calling handler\r\n if (res.headersSent) {\r\n return;\r\n }\r\n \r\n return await handler(context);\r\n } catch (error) {\r\n // If response is already sent, just log the error\r\n if (res.headersSent) {\r\n console.error('Error occurred after response was sent:', error);\r\n return;\r\n }\r\n \r\n const context: RouteContext = { req, res, next, params: req.params, query: req.query, body: req.body };\r\n return errorHandler(error, context);\r\n }\r\n };\r\n \r\n // Create routes from config\r\n Object.entries(routeConfig).forEach(([path, config]) => {\r\n const { method, handler } = config;\r\n router[method](path, handleRoute(handler));\r\n });\r\n \r\n return router;\r\n}\r\n\r\nexport { Router };\r\n","import { Request, Response, NextFunction, Router } from 'express';\r\nimport { ApiResponse, PaginationOptions, RouterOptions } from './types';\r\n\r\n/**\r\n * Creates a consistent API response structure\r\n */\r\nexport function apiResponse<T>(\r\n success: boolean, \r\n data?: T, \r\n message?: string, \r\n error?: string, \r\n meta?: Record<string, any>\r\n): ApiResponse<T> {\r\n const response: ApiResponse<T> = { success };\r\n \r\n if (data !== undefined) response.data = data;\r\n if (message) response.message = message;\r\n if (error) response.error = error;\r\n if (meta) response.meta = meta;\r\n \r\n return response;\r\n}\r\n\r\n/**\r\n * Helper to send successful responses\r\n */\r\nexport function sendSuccess<T>(\r\n res: Response, \r\n data?: T, \r\n message?: string, \r\n statusCode = 200,\r\n meta?: Record<string, any>\r\n): void {\r\n res.status(statusCode).json(apiResponse(true, data, message, undefined, meta));\r\n}\r\n\r\n/**\r\n * Helper to send error responses\r\n */\r\nexport function sendError(\r\n res: Response, \r\n error: string | Error, \r\n statusCode = 400,\r\n meta?: Record<string, any>\r\n): void {\r\n const errorMessage = error instanceof Error ? error.message : error;\r\n res.status(statusCode).json(apiResponse(false, undefined, undefined, errorMessage, meta));\r\n}\r\n\r\n/**\r\n * Helper to extract pagination parameters from request\r\n */\r\nexport function getPaginationParams(req: Request): PaginationOptions {\r\n const page = parseInt(req.query.page as string) || 1;\r\n const limit = parseInt(req.query.limit as string) || 10;\r\n const sort = (req.query.sort as string) || 'createdAt';\r\n const order = (req.query.order as string) === 'asc' ? 'asc' : 'desc';\r\n \r\n return { page, limit, sort, order };\r\n}\r\n\r\n/**\r\n * Middleware to extract and validate pagination parameters\r\n */\r\nexport function paginationMiddleware(\r\n req: Request, \r\n res: Response, \r\n next: NextFunction\r\n): void {\r\n req.pagination = getPaginationParams(req);\r\n next();\r\n}\r\n\r\n/**\r\n * Middleware for basic request validation\r\n */\r\nexport function validateRequest(schema: any) {\r\n return (req: Request, res: Response, next: NextFunction): void => {\r\n try {\r\n const { error, value } = schema.validate(req.body);\r\n \r\n if (error) {\r\n sendError(res, `Validation error: ${error.message}`, 400);\r\n return;\r\n }\r\n \r\n // Replace request body with validated value\r\n req.body = value;\r\n next();\r\n } catch (err) {\r\n sendError(res, 'Validation error', 400);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Create a new router with common middleware and options\r\n */\r\nexport function createApiRouter(options: RouterOptions = {}, auth?: any): Router {\r\n const router = Router();\r\n \r\n // Add authentication middleware if required\r\n if (options.requireAuth && auth) {\r\n router.use(auth.authenticate);\r\n \r\n // Add role check if specified\r\n if (options.requiredRole) {\r\n router.use(auth.hasRole(options.requiredRole));\r\n }\r\n }\r\n \r\n // Add rate limiting if specified\r\n if (options.rateLimit) {\r\n console.warn('Rate limiting is disabled: express-rate-limit dependency is not installed');\r\n // Note: To use rate limiting, install express-rate-limit: npm install express-rate-limit\r\n }\r\n \r\n return router;\r\n}\r\n\r\n/**\r\n * Wrap an async route handler to catch errors\r\n */\r\nexport function asyncHandler(\r\n fn: (req: Request, res: Response, next: NextFunction) => Promise<any>\r\n) {\r\n return (req: Request, res: Response, next: NextFunction): void => {\r\n fn(req, res, next).catch(next);\r\n };\r\n}\r\n\r\n/**\r\n * Create standard REST endpoints for a model\r\n */\r\nexport function createRestEndpoints<T>(model: any) {\r\n const router = Router();\r\n \r\n // GET all with pagination\r\n router.get('/', paginationMiddleware, asyncHandler(async (req, res) => {\r\n const result = await model.getAll(req.pagination);\r\n sendSuccess(res, result);\r\n }));\r\n \r\n // GET by ID\r\n router.get('/:id', asyncHandler(async (req, res) => {\r\n const item = await model.getById(req.params.id);\r\n if (!item) {\r\n return sendError(res, 'Item not found', 404);\r\n }\r\n sendSuccess(res, item);\r\n }));\r\n \r\n // POST new item\r\n router.post('/', asyncHandler(async (req, res) => {\r\n const newItem = await model.create(req.body);\r\n sendSuccess(res, newItem, 'Item created successfully', 201);\r\n }));\r\n \r\n // PUT update item\r\n router.put('/:id', asyncHandler(async (req, res) => {\r\n const updatedItem = await model.update(req.params.id, req.body);\r\n if (!updatedItem) {\r\n return sendError(res, 'Item not found', 404);\r\n }\r\n sendSuccess(res, updatedItem, 'Item updated successfully');\r\n }));\r\n \r\n // DELETE item\r\n router.delete('/:id', asyncHandler(async (req, res) => {\r\n const result = await model.delete(req.params.id);\r\n if (!result) {\r\n return sendError(res, 'Item not found', 404);\r\n }\r\n sendSuccess(res, null, 'Item deleted successfully');\r\n }));\r\n \r\n return router;\r\n}\r\n","export default {}","import { Request, Response, NextFunction } from 'express';\r\nimport jwt from 'jsonwebtoken';\r\nimport bcrypt from 'bcrypt';\r\nimport crypto from 'crypto';\r\n\r\n/**\r\n * Authentication configuration options\r\n */\r\nexport interface AuthOptions {\r\n /**\r\n * Secret key for JWT signing\r\n */\r\n jwtSecret: string;\r\n \r\n /**\r\n * Secret key for refresh token signing (defaults to jwtSecret if not provided)\r\n */\r\n refreshSecret?: string;\r\n \r\n /**\r\n * JWT token expiration time (default: '15m')\r\n */\r\n tokenExpiration?: string;\r\n \r\n /**\r\n * Refresh token expiration time (default: '7d')\r\n */\r\n refreshExpiration?: string;\r\n \r\n /**\r\n * Number of bcrypt salt rounds (default: 10)\r\n */\r\n saltRounds?: number;\r\n \r\n /**\r\n * Custom user finder function\r\n */\r\n findUser?: (username: string) => Promise<any>;\r\n \r\n /**\r\n * Custom password verification (defaults to bcrypt compare)\r\n */\r\n verifyPassword?: (password: string, hashedPassword: string) => Promise<boolean>;\r\n \r\n /**\r\n * Custom function to save refresh token\r\n */\r\n saveRefreshToken?: (userId: string, token: string, expires: Date) => Promise<void>;\r\n \r\n /**\r\n * Custom function to verify refresh token\r\n */\r\n verifyRefreshToken?: (userId: string, token: string) => Promise<boolean>;\r\n \r\n /**\r\n * Use secure cookies for tokens (default: process.env.NODE_ENV === 'production')\r\n */\r\n secureCookies?: boolean;\r\n \r\n /**\r\n * Cookie domain\r\n */\r\n cookieDomain?: string;\r\n \r\n /**\r\n * Use HTTP-only cookies (default: true)\r\n */\r\n httpOnlyCookies?: boolean;\r\n \r\n /**\r\n * Implement rate limiting for login attempts (default: true)\r\n */\r\n rateLimit?: boolean;\r\n}\r\n\r\n/**\r\n * Token pair containing access and refresh tokens\r\n */\r\nexport interface TokenPair {\r\n accessToken: string;\r\n refreshToken: string;\r\n expiresIn: number;\r\n}\r\n\r\n/**\r\n * Authentication service\r\n */\r\nexport class Auth {\r\n private options: AuthOptions;\r\n private loginAttempts: Map<string, { count: number, resetTime: number }> = new Map();\r\n \r\n constructor(options: AuthOptions) {\r\n this.options = {\r\n tokenExpiration: '15m',\r\n refreshExpiration: '7d',\r\n saltRounds: 10,\r\n secureCookies: process.env.NODE_ENV === 'production',\r\n httpOnlyCookies: true,\r\n rateLimit: true,\r\n ...options,\r\n refreshSecret: options.refreshSecret || options.jwtSecret\r\n };\r\n \r\n if (!options.jwtSecret) {\r\n throw new Error('JWT secret is required for authentication');\r\n }\r\n \r\n // Set default password verification if not provided\r\n if (!this.options.verifyPassword) {\r\n this.options.verifyPassword = this.verifyPasswordWithBcrypt;\r\n }\r\n }\r\n \r\n /**\r\n * Hash a password using bcrypt\r\n */\r\n async hashPassword(password: string): Promise<string> {\r\n return await bcrypt.hash(password, this.options.saltRounds || 10);\r\n }\r\n \r\n /**\r\n * Verify a password against a hash using bcrypt\r\n */\r\n private async verifyPasswordWithBcrypt(password: string, hashedPassword: string): Promise<boolean> {\r\n return await bcrypt.compare(password, hashedPassword);\r\n }\r\n \r\n /**\r\n * Generate a cryptographically secure random token\r\n */\r\n generateSecureToken(length = 32): string {\r\n return crypto.randomBytes(length).toString('hex');\r\n }\r\n \r\n /**\r\n * Generate token pair (access token + refresh token)\r\n */\r\n generateTokenPair(payload: any): TokenPair {\r\n // Calculate expiration times\r\n const expiresIn = this.getExpirationSeconds(this.options.tokenExpiration || '15m');\r\n \r\n // Generate the access token\r\n const accessToken = jwt.sign(\r\n { ...payload, type: 'access' }, \r\n this.options.jwtSecret, \r\n { expiresIn: this.options.tokenExpiration }\r\n );\r\n \r\n // Generate the refresh token\r\n const refreshToken = jwt.sign(\r\n { id: payload.id, type: 'refresh' },\r\n this.options.refreshSecret!,\r\n { expiresIn: this.options.refreshExpiration }\r\n );\r\n \r\n return {\r\n accessToken,\r\n refreshToken,\r\n expiresIn\r\n };\r\n }\r\n \r\n /**\r\n * Convert JWT expiration time to seconds\r\n */\r\n private getExpirationSeconds(expiration: string): number {\r\n const unit = expiration.charAt(expiration.length - 1);\r\n const value = parseInt(expiration.slice(0, -1));\r\n \r\n switch (unit) {\r\n case 's': return value;\r\n case 'm': return value * 60;\r\n case 'h': return value * 60 * 60;\r\n case 'd': return value * 60 * 60 * 24;\r\n default: return 3600; // Default 1 hour\r\n }\r\n }\r\n \r\n /**\r\n * Verify a JWT token\r\n */\r\n verifyToken(token: string, type: 'access' | 'refresh' = 'access'): any {\r\n try {\r\n const secret = type === 'access' ? this.options.jwtSecret : this.options.refreshSecret;\r\n const decoded = jwt.verify(token, secret!);\r\n \r\n // Verify token type matches expected type\r\n if (typeof decoded === 'object' && decoded.type !== type) {\r\n throw new Error('Invalid token type');\r\n }\r\n \r\n return decoded;\r\n } catch (error) {\r\n throw new Error('Invalid or expired token');\r\n }\r\n }\r\n \r\n /**\r\n * Set authentication cookies\r\n */\r\n setAuthCookies(res: Response, tokens: TokenPair): void {\r\n // Set access token cookie\r\n res.cookie('accessToken', tokens.accessToken, {\r\n httpOnly: this.options.httpOnlyCookies,\r\n secure: this.options.secureCookies,\r\n domain: this.options.cookieDomain,\r\n sameSite: 'strict',\r\n maxAge: tokens.expiresIn * 1000\r\n });\r\n \r\n // Set refresh token cookie with longer expiration\r\n const refreshExpiresIn = this.getExpirationSeconds(this.options.refreshExpiration || '7d');\r\n res.cookie('refreshToken', tokens.refreshToken, {\r\n httpOnly: true, // Always HTTP only for refresh tokens\r\n secure: this.options.secureCookies,\r\n domain: this.options.cookieDomain,\r\n sameSite: 'strict',\r\n maxAge: refreshExpiresIn * 1000,\r\n path: '/api/auth/refresh' // Restrict to refresh endpoint\r\n });\r\n }\r\n \r\n /**\r\n * Clear authentication cookies\r\n */\r\n clearAuthCookies(res: Response): void {\r\n res.clearCookie('accessToken');\r\n res.clearCookie('refreshToken', { path: '/api/auth/refresh' });\r\n }\r\n \r\n /**\r\n * Check and handle rate limiting\r\n */\r\n private checkRateLimit(ip: string): boolean {\r\n if (!this.options.rateLimit) {\r\n return true;\r\n }\r\n \r\n const now = Date.now();\r\n const attempt = this.loginAttempts.get(ip);\r\n \r\n if (!attempt) {\r\n this.loginAttempts.set(ip, { count: 1, resetTime: now + 3600000 });\r\n return true;\r\n }\r\n \r\n // Reset if time expired\r\n if (now > attempt.resetTime) {\r\n this.loginAttempts.set(ip, { count: 1, resetTime: now + 3600000 });\r\n return true;\r\n }\r\n \r\n // Check attempts\r\n if (attempt.count >= 5) {\r\n return false;\r\n }\r\n \r\n // Increment counter\r\n attempt.count++;\r\n this.loginAttempts.set(ip, attempt);\r\n return true;\r\n }\r\n \r\n /**\r\n * Login middleware to authenticate users\r\n */\r\n login = async (req: Request, res: Response): Promise<void> => {\r\n try {\r\n const { username, password } = req.body;\r\n const ip = req.ip || req.connection.remoteAddress || '';\r\n \r\n // Check rate limiting\r\n if (!this.checkRateLimit(ip)) {\r\n res.status(429).json({ \r\n success: false, \r\n message: 'Too many login attempts. Please try again later.' \r\n });\r\n return;\r\n }\r\n \r\n if (!username || !password) {\r\n res.status(400).json({ \r\n success: false, \r\n message: 'Username and password are required' \r\n });\r\n return;\r\n }\r\n \r\n // Use custom find user function if provided\r\n if (!this.options.findUser) {\r\n res.status(500).json({ \r\n success: false, \r\n message: 'User finder function not configured' \r\n });\r\n return;\r\n }\r\n \r\n const user = await this.options.findUser(username);\r\n \r\n if (!user) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Invalid credentials' \r\n });\r\n return;\r\n }\r\n \r\n // Verify password\r\n const isPasswordValid = await this.options.verifyPassword!(\r\n password, \r\n user.password\r\n );\r\n \r\n if (!isPasswordValid) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Invalid credentials' \r\n });\r\n return;\r\n }\r\n \r\n // Create a sanitized user object (without password)\r\n const userWithoutPassword = { ...user };\r\n delete userWithoutPassword.password;\r\n \r\n // Generate tokens\r\n const tokenPair = this.generateTokenPair({\r\n id: user.id || user._id,\r\n username: user.username,\r\n role: user.role || 'user'\r\n });\r\n \r\n // Save refresh token if the function is provided\r\n if (this.options.saveRefreshToken) {\r\n const refreshExpiry = new Date();\r\n refreshExpiry.setSeconds(refreshExpiry.getSeconds() + \r\n this.getExpirationSeconds(this.options.refreshExpiration || '7d'));\r\n \r\n await this.options.saveRefreshToken(\r\n user.id || user._id,\r\n tokenPair.refreshToken,\r\n refreshExpiry\r\n );\r\n }\r\n \r\n // Set authentication cookies if using cookie-based auth\r\n if (req.body.useCookies) {\r\n this.setAuthCookies(res, tokenPair);\r\n }\r\n \r\n res.json({\r\n success: true,\r\n message: 'Authentication successful',\r\n tokens: tokenPair,\r\n user: userWithoutPassword\r\n });\r\n } catch (error) {\r\n console.error('Authentication error:', error);\r\n res.status(500).json({ \r\n success: false, \r\n message: 'Authentication failed',\r\n error: process.env.NODE_ENV !== 'production' ? (error as Error).message : undefined\r\n });\r\n }\r\n };\r\n \r\n /**\r\n * Refresh token handler\r\n */\r\n refreshToken = async (req: Request, res: Response): Promise<void> => {\r\n try {\r\n // Get refresh token from cookies or request body\r\n const refreshToken = req.cookies?.refreshToken || req.body.refreshToken;\r\n \r\n if (!refreshToken) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Refresh token required' \r\n });\r\n return;\r\n }\r\n \r\n // Verify the refresh token\r\n const decoded = this.verifyToken(refreshToken, 'refresh');\r\n \r\n // Check if token is still valid in database if verification function provided\r\n if (this.options.verifyRefreshToken) {\r\n const isValid = await this.options.verifyRefreshToken(decoded.id, refreshToken);\r\n if (!isValid) {\r\n this.clearAuthCookies(res);\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Invalid refresh token' \r\n });\r\n return;\r\n }\r\n }\r\n \r\n // Generate new token pair\r\n const tokenPair = this.generateTokenPair({\r\n id: decoded.id,\r\n // We need to fetch the user data again for complete payload\r\n ...(this.options.findUser ? await this.options.findUser(decoded.id) : {})\r\n });\r\n \r\n // Update refresh token in database if save function provided\r\n if (this.options.saveRefreshToken) {\r\n const refreshExpiry = new Date();\r\n refreshExpiry.setSeconds(refreshExpiry.getSeconds() + \r\n this.getExpirationSeconds(this.options.refreshExpiration || '7d'));\r\n \r\n await this.options.saveRefreshToken(\r\n decoded.id,\r\n tokenPair.refreshToken,\r\n refreshExpiry\r\n );\r\n }\r\n \r\n // Set cookies if cookie-based auth is used\r\n const useCookies = req.cookies?.accessToken || req.body.useCookies;\r\n if (useCookies) {\r\n this.setAuthCookies(res, tokenPair);\r\n }\r\n \r\n res.json({\r\n success: true,\r\n message: 'Token refreshed successfully',\r\n tokens: tokenPair\r\n });\r\n } catch (error) {\r\n this.clearAuthCookies(res);\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Invalid or expired refresh token',\r\n error: process.env.NODE_ENV !== 'production' ? (error as Error).message : undefined\r\n });\r\n }\r\n };\r\n \r\n /**\r\n * Logout handler\r\n */\r\n logout = async (req: Request, res: Response): Promise<void> => {\r\n try {\r\n // Clear cookies\r\n this.clearAuthCookies(res);\r\n \r\n // Invalidate refresh token if verification function provided\r\n const refreshToken = req.cookies?.refreshToken || req.body.refreshToken;\r\n if (refreshToken && this.options.saveRefreshToken) {\r\n try {\r\n const decoded = this.verifyToken(refreshToken, 'refresh');\r\n \r\n // Check if invalidateToken function exists, otherwise we just remove it from storage\r\n if (typeof this.options.saveRefreshToken === 'function') {\r\n // We pass null as the token to indicate deletion/invalidation\r\n await this.options.saveRefreshToken(decoded.id, '', new Date());\r\n }\r\n } catch (e) {\r\n // Token already invalid, nothing to do\r\n }\r\n }\r\n \r\n res.json({ success: true, message: 'Logged out successfully' });\r\n } catch (error) {\r\n console.error('Logout error:', error);\r\n res.status(500).json({ success: false, message: 'Logout failed', error: (error as Error).message });\r\n }\r\n };\r\n \r\n /**\r\n * Middleware to verify user is authenticated\r\n */\r\n authenticate = (req: Request, res: Response, next: NextFunction): void => {\r\n try {\r\n // Get token from Authorization header or cookies\r\n let token = req.cookies?.accessToken;\r\n \r\n if (!token) {\r\n const authHeader = req.headers.authorization;\r\n if (authHeader && authHeader.startsWith('Bearer ')) {\r\n token = authHeader.split(' ')[1];\r\n }\r\n }\r\n \r\n if (!token) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Authentication required' \r\n });\r\n return;\r\n }\r\n \r\n const decoded = this.verifyToken(token, 'access');\r\n \r\n // Add user info to request\r\n (req as any).user = decoded;\r\n \r\n next();\r\n } catch (error) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Invalid or expired token',\r\n error: process.env.NODE_ENV !== 'production' ? (error as Error).message : undefined\r\n });\r\n }\r\n };\r\n \r\n /**\r\n * Middleware to check if user has required role\r\n */\r\n hasRole = (role: string | string[]) => {\r\n return (req: Request, res: Response, next: NextFunction): void => {\r\n const user = (req as any).user;\r\n \r\n if (!user) {\r\n res.status(401).json({ \r\n success: false, \r\n message: 'Authentication required' \r\n });\r\n return;\r\n }\r\n \r\n const roles = Array.isArray(role) ? role : [role];\r\n \r\n if (roles.includes(user.role)) {\r\n next();\r\n } else {\r\n res.status(403).json({ \r\n success: false, \r\n message: 'Insufficient permissions' \r\n });\r\n }\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Create an authentication service\r\n */\r\nexport function createAuth(options: AuthOptions): Auth {\r\n return new Auth(options);\r\n}","import mongoose, { Schema, Document, SortOrder } from 'mongoose';\r\nimport { Model, PaginationOptions, PaginatedResult } from './types';\r\n\r\n/**\r\n * Creates a data model from a Mongoose schema\r\n * @param name Model name\r\n * @param schema Mongoose schema definition\r\n * @returns Model implementation with CRUD operations\r\n */\r\nexport function createModel<T extends Document>(\r\n name: string, \r\n schema: Schema<T>\r\n): Model<T> {\r\n // Create the Mongoose model\r\n const mongooseModel = mongoose.model<T>(name, schema);\r\n \r\n // Return the model implementation with CRUD operations\r\n return {\r\n getAll: async (options?: PaginationOptions): Promise<PaginatedResult<T>> => {\r\n try {\r\n const { page = 1, limit = 10, sort = '_id', order = 'desc' } = options || {};\r\n \r\n const skip = (page - 1) * limit;\r\n const sortOrder = order === 'asc' ? 1 : -1;\r\n const sortOptions: Record<string, SortOrder> = { [sort]: sortOrder };\r\n \r\n const [results, total] = await Promise.all([\r\n mongooseModel.find()\r\n .sort(sortOptions as any)\r\n .skip(skip)\r\n .limit(limit)\r\n .exec(),\r\n mongooseModel.countDocuments().exec()\r\n ]);\r\n \r\n const totalPages = Math.ceil(total / limit);\r\n \r\n return {\r\n data: results,\r\n pagination: {\r\n total,\r\n totalPages,\r\n currentPage: page,\r\n limit,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1\r\n }\r\n };\r\n } catch (error) {\r\n console.error(`Error in ${name}.getAll:`, error);\r\n throw new Error(`Failed to retrieve ${name} records: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n getById: async (id: string): Promise<T | null> => {\r\n try {\r\n // Validate ObjectId format to prevent DB errors\r\n if (!mongoose.isValidObjectId(id)) {\r\n return null;\r\n }\r\n return await mongooseModel.findById(id).exec();\r\n } catch (error) {\r\n console.error(`Error in ${name}.getById:`, error);\r\n throw new Error(`Failed to retrieve ${name} by ID: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n create: async (data: Partial<T>): Promise<T> => {\r\n try {\r\n const newDocument = new mongooseModel(data);\r\n return await newDocument.save();\r\n } catch (error) {\r\n console.error(`Error in ${name}.create:`, error);\r\n throw new Error(`Failed to create ${name}: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n createMany: async (data: Partial<T>[]): Promise<T[]> => {\r\n try {\r\n return await mongooseModel.insertMany(data) as unknown as T[];\r\n } catch (error) {\r\n console.error(`Error in ${name}.createMany:`, error);\r\n throw new Error(`Failed to create multiple ${name} records: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n update: async (id: string, data: Partial<T>): Promise<T | null> => {\r\n try {\r\n // Validate ObjectId format to prevent DB errors\r\n if (!mongoose.isValidObjectId(id)) {\r\n return null;\r\n }\r\n return await mongooseModel.findByIdAndUpdate(\r\n id, \r\n { $set: data }, \r\n { new: true, runValidators: true }\r\n ).exec();\r\n } catch (error) {\r\n console.error(`Error in ${name}.update:`, error);\r\n throw new Error(`Failed to update ${name}: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n delete: async (id: string): Promise<boolean> => {\r\n try {\r\n // Validate ObjectId format to prevent DB errors\r\n if (!mongoose.isValidObjectId(id)) {\r\n return false;\r\n }\r\n const result = await mongooseModel.findByIdAndDelete(id).exec();\r\n return result !== null;\r\n } catch (error) {\r\n console.error(`Error in ${name}.delete:`, error);\r\n throw new Error(`Failed to delete ${name}: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n find: async (query: Record<string, any>, options?: PaginationOptions): Promise<PaginatedResult<T>> => {\r\n try {\r\n const { page = 1, limit = 10, sort = '_id', order = 'desc' } = options || {};\r\n \r\n const skip = (page - 1) * limit;\r\n const sortOrder = order === 'asc' ? 1 : -1;\r\n const sortOptions: Record<string, SortOrder> = { [sort]: sortOrder };\r\n \r\n const [results, total] = await Promise.all([\r\n mongooseModel.find(query)\r\n .sort(sortOptions as any)\r\n .skip(skip)\r\n .limit(limit)\r\n .exec(),\r\n mongooseModel.countDocuments(query).exec()\r\n ]);\r\n \r\n const totalPages = Math.ceil(total / limit);\r\n \r\n return {\r\n data: results,\r\n pagination: {\r\n total,\r\n totalPages,\r\n currentPage: page,\r\n limit,\r\n hasNextPage: page < totalPages,\r\n hasPrevPage: page > 1\r\n }\r\n };\r\n } catch (error) {\r\n console.error(`Error in ${name}.find:`, error);\r\n throw new Error(`Failed to find ${name} records: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n count: async (query?: Record<string, any>): Promise<number> => {\r\n try {\r\n return await mongooseModel.countDocuments(query || {}).exec();\r\n } catch (error) {\r\n console.error(`Error in ${name}.count:`, error);\r\n throw new Error(`Failed to count ${name} records: ${(error as Error).message}`);\r\n }\r\n },\r\n \r\n findOne: async (query: Record<string, any>): Promise<T | null> => {\r\n try {\r\n return await mongooseModel.findOne(query).exec();\r\n } catch (error) {\r\n console.error(`Error in ${name}.findOne:`, error);\r\n throw new Error(`Failed to find ${name} record: ${(error as Error).message}`);\r\n }\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Schema field types for simplified schema creation\r\n */\r\nexport const FieldTypes = {\r\n String: { type: String },\r\n Number: { type: Number },\r\n Boolean: { type: Boolean },\r\n Date: { type: Date },\r\n ObjectId: { type: String }, // Fallback to String instead of using Schema.Types.ObjectId\r\n \r\n // Helper functions for common field patterns\r\n Required: (fieldType: any) => ({ ...fieldType, required: true }),\r\n Unique: (fieldType: any) => ({ ...fieldType, unique: true }),\r\n Ref: (model: string) => ({ \r\n type: String, // Fallback to String type for tests\r\n ref: model \r\n }),\r\n Enum: (values: any[]) => ({ type: String, enum: values }),\r\n Default: (fieldType: any, defaultValue: any) => ({ ...fieldType, default: defaultValue }),\r\n \r\n // Array field type\r\n Array: (fieldType: any) => ({ type: [fieldType] })\r\n};","// Frontend exports\r\nimport { jsx, jsxs, createElement, Fragment } from './jsx-runtime/index';\r\nimport { Component } from './component';\r\nimport { useState, useEffect, useRef, useMemo, useErrorBoundary } from './hooks';\r\nimport { render, hydrate } from './renderer';\r\nimport { renderToString } from './server-renderer';\r\nimport { prepareRender, finishRender } from './hooks';\r\nimport { batchUpdates } from './batch';\r\n\r\n// Backend functionality\r\nimport { createServer } from './backend/server';\r\nimport { Router } from './backend/router';\r\nimport { createApiRouter } from './backend/api-utils';\r\n\r\n// Export JSX runtime\r\nexport {\r\n jsx,\r\n jsxs,\r\n createElement,\r\n Fragment\r\n};\r\n\r\n// Export hooks\r\nexport {\r\n useState,\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useErrorBoundary,\r\n prepareRender,\r\n finishRender,\r\n batchUpdates\r\n};\r\n\r\n// Export component base class\r\nexport { Component };\r\n\r\n// Export renderers\r\nexport {\r\n render,\r\n hydrate,\r\n renderToString\r\n};\r\n// Export backend functionality\r\nexport {\r\n createServer,\r\n Router,\r\n createApiRouter\r\n};\r\n\r\n// Default export with all functionality\r\nexport default {\r\n // Frontend\r\n jsx,\r\n jsxs,\r\n createElement,\r\n Fragment,\r\n Component,\r\n useState,\r\n useEffect,\r\n useRef,\r\n useMemo,\r\n useErrorBoundary,\r\n render,\r\n hydrate,\r\n renderToString,\r\n prepareRender,\r\n finishRender,\r\n batchUpdates,\r\n \r\n // Backend\r\n createServer,\r\n Router,\r\n createApiRouter\r\n};\r\n\r\n// Re-export types\r\nexport type { Context } from './context';\r\nexport type { VNode } from './types';\r\n\r\n// Backend exports\r\nexport { createAuth } from './backend/auth';\r\nexport { createModel, FieldTypes } from './backend/model';\r\nexport { createModelRouter, createApiRouter as createCustomRouter } from './backend/router';\r\nexport { \r\n sendSuccess, \r\n sendError, \r\n apiResponse, \r\n getPaginationParams, \r\n paginationMiddleware,\r\n validateRequest,\r\n asyncHandler,\r\n createRestEndpoints\r\n} from './backend/api-utils';\r\nexport { DatabaseConnector } from './backend/database';\r\n\r\n// Backend types\r\nexport type {\r\n HamrounServerOptions,\r\n RouterOptions,\r\n RouteContext,\r\n PaginationOptions,\r\n PaginatedResult,\r\n DatabaseOptions,\r\n Model,\r\n ApiResponse\r\n} from './backend/types';\r\n\r\nexport type {\r\n AuthOptions,\r\n TokenPair\r\n} from './backend/auth';\r\n\r\n"],"names":["createElement","fs","path","index","state","setState","ref","html","options","createApiRouter"],"mappings":"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"}
|