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,547 +1,467 @@
|
|
1
|
-
import
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import
|
11
|
-
const
|
12
|
-
function
|
1
|
+
import O, { Router as ye } from "express";
|
2
|
+
import de from "path";
|
3
|
+
import Ne from "compression";
|
4
|
+
import Oe from "helmet";
|
5
|
+
import Pe from "morgan";
|
6
|
+
import $ from "mongoose";
|
7
|
+
import De from "fs";
|
8
|
+
import z from "jsonwebtoken";
|
9
|
+
import * as fe from "bcrypt";
|
10
|
+
import Me from "crypto";
|
11
|
+
const he = globalThis || void 0 || self;
|
12
|
+
function Fe(r) {
|
13
|
+
return r && r.__esModule && Object.prototype.hasOwnProperty.call(r, "default") ? r.default : r;
|
14
|
+
}
|
15
|
+
var ge = { exports: {} }, m = ge.exports = {}, k, v;
|
16
|
+
function te() {
|
17
|
+
throw new Error("setTimeout has not been defined");
|
18
|
+
}
|
19
|
+
function re() {
|
20
|
+
throw new Error("clearTimeout has not been defined");
|
21
|
+
}
|
22
|
+
(function() {
|
23
|
+
try {
|
24
|
+
typeof setTimeout == "function" ? k = setTimeout : k = te;
|
25
|
+
} catch {
|
26
|
+
k = te;
|
27
|
+
}
|
28
|
+
try {
|
29
|
+
typeof clearTimeout == "function" ? v = clearTimeout : v = re;
|
30
|
+
} catch {
|
31
|
+
v = re;
|
32
|
+
}
|
33
|
+
})();
|
34
|
+
function we(r) {
|
35
|
+
if (k === setTimeout)
|
36
|
+
return setTimeout(r, 0);
|
37
|
+
if ((k === te || !k) && setTimeout)
|
38
|
+
return k = setTimeout, setTimeout(r, 0);
|
39
|
+
try {
|
40
|
+
return k(r, 0);
|
41
|
+
} catch {
|
42
|
+
try {
|
43
|
+
return k.call(null, r, 0);
|
44
|
+
} catch {
|
45
|
+
return k.call(this, r, 0);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
function Le(r) {
|
50
|
+
if (v === clearTimeout)
|
51
|
+
return clearTimeout(r);
|
52
|
+
if ((v === re || !v) && clearTimeout)
|
53
|
+
return v = clearTimeout, clearTimeout(r);
|
54
|
+
try {
|
55
|
+
return v(r);
|
56
|
+
} catch {
|
57
|
+
try {
|
58
|
+
return v.call(null, r);
|
59
|
+
} catch {
|
60
|
+
return v.call(this, r);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
var A = [], D = !1, _, B = -1;
|
65
|
+
function Ve() {
|
66
|
+
!D || !_ || (D = !1, _.length ? A = _.concat(A) : B = -1, A.length && Ee());
|
67
|
+
}
|
68
|
+
function Ee() {
|
69
|
+
if (!D) {
|
70
|
+
var r = we(Ve);
|
71
|
+
D = !0;
|
72
|
+
for (var t = A.length; t; ) {
|
73
|
+
for (_ = A, A = []; ++B < t; )
|
74
|
+
_ && _[B].run();
|
75
|
+
B = -1, t = A.length;
|
76
|
+
}
|
77
|
+
_ = null, D = !1, Le(r);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
m.nextTick = function(r) {
|
81
|
+
var t = new Array(arguments.length - 1);
|
82
|
+
if (arguments.length > 1)
|
83
|
+
for (var e = 1; e < arguments.length; e++)
|
84
|
+
t[e - 1] = arguments[e];
|
85
|
+
A.push(new be(r, t)), A.length === 1 && !D && we(Ee);
|
86
|
+
};
|
87
|
+
function be(r, t) {
|
88
|
+
this.fun = r, this.array = t;
|
89
|
+
}
|
90
|
+
be.prototype.run = function() {
|
91
|
+
this.fun.apply(null, this.array);
|
92
|
+
};
|
93
|
+
m.title = "browser";
|
94
|
+
m.browser = !0;
|
95
|
+
m.env = {};
|
96
|
+
m.argv = [];
|
97
|
+
m.version = "";
|
98
|
+
m.versions = {};
|
99
|
+
function x() {
|
100
|
+
}
|
101
|
+
m.on = x;
|
102
|
+
m.addListener = x;
|
103
|
+
m.once = x;
|
104
|
+
m.off = x;
|
105
|
+
m.removeListener = x;
|
106
|
+
m.removeAllListeners = x;
|
107
|
+
m.emit = x;
|
108
|
+
m.prependListener = x;
|
109
|
+
m.prependOnceListener = x;
|
110
|
+
m.listeners = function(r) {
|
111
|
+
return [];
|
112
|
+
};
|
113
|
+
m.binding = function(r) {
|
114
|
+
throw new Error("process.binding is not supported");
|
115
|
+
};
|
116
|
+
m.cwd = function() {
|
117
|
+
return "/";
|
118
|
+
};
|
119
|
+
m.chdir = function(r) {
|
120
|
+
throw new Error("process.chdir is not supported");
|
121
|
+
};
|
122
|
+
m.umask = function() {
|
123
|
+
return 0;
|
124
|
+
};
|
125
|
+
var Be = ge.exports;
|
126
|
+
const w = /* @__PURE__ */ Fe(Be), j = typeof window < "u" ? window : typeof he < "u" ? he : {};
|
127
|
+
function ae(r, t, e) {
|
13
128
|
return {
|
14
|
-
type,
|
15
|
-
props:
|
16
|
-
key
|
129
|
+
type: r,
|
130
|
+
props: t || {},
|
131
|
+
key: e
|
17
132
|
};
|
18
133
|
}
|
19
|
-
function
|
20
|
-
return
|
134
|
+
function Te(r, t, e) {
|
135
|
+
return ae(r, t, e);
|
21
136
|
}
|
22
|
-
function
|
23
|
-
if (typeof
|
24
|
-
return document.createTextNode(String(
|
137
|
+
function se(r) {
|
138
|
+
if (typeof r == "string" || typeof r == "number")
|
139
|
+
return document.createTextNode(String(r));
|
140
|
+
if (typeof r.type == "function") {
|
141
|
+
const e = r.type(r.props);
|
142
|
+
return se(e);
|
25
143
|
}
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
renderTime: 0
|
44
|
-
};
|
45
|
-
if (typeof afterAll === "function") {
|
46
|
-
afterAll(() => {
|
47
|
-
try {
|
48
|
-
const fs2 = require("fs");
|
49
|
-
const path2 = require("path");
|
50
|
-
const statsPath = path2.resolve(process.cwd(), "jsx-runtime-stats.json");
|
51
|
-
fs2.writeFileSync(statsPath, JSON.stringify(globalObj.__renderStats, null, 2));
|
52
|
-
console.log(`JSX runtime stats written to ${statsPath}`);
|
53
|
-
} catch (error) {
|
54
|
-
console.error("Failed to write stats file:", error);
|
55
|
-
}
|
56
|
-
});
|
57
|
-
}
|
58
|
-
}
|
59
|
-
if (childElement instanceof Text) {
|
60
|
-
globalObj.__renderStats.textNodesCreated++;
|
61
|
-
} else {
|
62
|
-
globalObj.__renderStats.elementsCreated++;
|
144
|
+
const t = document.createElement(r.type);
|
145
|
+
return Object.entries(r.props || {}).forEach(([e, s]) => {
|
146
|
+
if (e === "children")
|
147
|
+
(Array.isArray(s) ? s : [s]).forEach((i) => {
|
148
|
+
if (i != null) {
|
149
|
+
const o = se(i);
|
150
|
+
w.env.NODE_ENV === "test" && typeof window < "u" && (j.__renderStats || (j.__renderStats = {
|
151
|
+
elementsCreated: 0,
|
152
|
+
textNodesCreated: 0,
|
153
|
+
eventsAttached: 0,
|
154
|
+
renderTime: 0
|
155
|
+
}, typeof afterAll == "function" && afterAll(() => {
|
156
|
+
try {
|
157
|
+
const a = require("fs"), d = require("path").resolve(w.cwd(), "jsx-runtime-stats.json");
|
158
|
+
a.writeFileSync(d, JSON.stringify(j.__renderStats, null, 2)), console.log(`JSX runtime stats written to ${d}`);
|
159
|
+
} catch (a) {
|
160
|
+
console.error("Failed to write stats file:", a);
|
63
161
|
}
|
64
|
-
}
|
65
|
-
element.appendChild(childElement);
|
162
|
+
})), o instanceof Text ? j.__renderStats.textNodesCreated++ : j.__renderStats.elementsCreated++), t.appendChild(o);
|
66
163
|
}
|
67
164
|
});
|
68
|
-
|
69
|
-
const
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
element.setAttribute("class", value);
|
76
|
-
} else if (name === "style" && typeof value === "object") {
|
77
|
-
Object.entries(value).forEach(([styleProp, styleValue]) => {
|
78
|
-
element.style[styleProp] = String(styleValue);
|
79
|
-
});
|
80
|
-
} else {
|
81
|
-
element.setAttribute(name, value);
|
82
|
-
}
|
83
|
-
});
|
84
|
-
return element;
|
165
|
+
else if (e.startsWith("on")) {
|
166
|
+
const n = e.toLowerCase().substring(2);
|
167
|
+
t.addEventListener(n, s), w.env.NODE_ENV === "test" && typeof window < "u" && j.__renderStats && j.__renderStats.eventsAttached++;
|
168
|
+
} else e === "className" ? t.setAttribute("class", s) : e === "style" && typeof s == "object" ? Object.entries(s).forEach(([n, i]) => {
|
169
|
+
t.style[n] = String(i);
|
170
|
+
}) : t.setAttribute(e, s);
|
171
|
+
}), t;
|
85
172
|
}
|
86
|
-
const
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
async function createElement(vnode) {
|
94
|
-
var _a;
|
95
|
-
console.log("Creating element from:", vnode);
|
96
|
-
if (!isBrowser) {
|
97
|
-
if (vnode == null) {
|
173
|
+
const ke = Symbol("Fragment");
|
174
|
+
typeof window < "u" && (window.jsx = ae, window.jsxs = Te, window.Fragment = ke);
|
175
|
+
const He = typeof window < "u" && typeof document < "u";
|
176
|
+
async function C(r) {
|
177
|
+
var t;
|
178
|
+
if (console.log("Creating element from:", r), !He) {
|
179
|
+
if (r == null)
|
98
180
|
return { nodeType: 3, textContent: "" };
|
99
|
-
|
100
|
-
if (typeof vnode === "boolean") {
|
181
|
+
if (typeof r == "boolean")
|
101
182
|
return { nodeType: 3, textContent: "" };
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
const node = await createElement(child);
|
110
|
-
fragment.childNodes.push(node);
|
183
|
+
if (typeof r == "number" || typeof r == "string")
|
184
|
+
return { nodeType: 3, textContent: String(r) };
|
185
|
+
if (Array.isArray(r)) {
|
186
|
+
const e = { nodeType: 11, childNodes: [] };
|
187
|
+
for (const s of r) {
|
188
|
+
const n = await C(s);
|
189
|
+
e.childNodes.push(n);
|
111
190
|
}
|
112
|
-
return
|
191
|
+
return e;
|
113
192
|
}
|
114
|
-
if ("type" in
|
115
|
-
const { type, props } =
|
116
|
-
if (typeof
|
193
|
+
if ("type" in r && r.props !== void 0) {
|
194
|
+
const { type: e, props: s } = r;
|
195
|
+
if (typeof e == "function")
|
117
196
|
try {
|
118
|
-
const
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
console.error("Error rendering component:", error);
|
123
|
-
return { nodeType: 3, textContent: "" };
|
197
|
+
const o = await e(s || {});
|
198
|
+
return await C(o);
|
199
|
+
} catch (o) {
|
200
|
+
return console.error("Error rendering component:", o), { nodeType: 3, textContent: "" };
|
124
201
|
}
|
125
|
-
|
126
|
-
const element = {
|
202
|
+
const n = {
|
127
203
|
nodeType: 1,
|
128
|
-
tagName:
|
204
|
+
tagName: e,
|
129
205
|
attributes: {},
|
130
206
|
style: {},
|
131
207
|
childNodes: [],
|
132
|
-
setAttribute: function(
|
133
|
-
this.attributes[
|
208
|
+
setAttribute: function(o, a) {
|
209
|
+
this.attributes[o] = a;
|
134
210
|
},
|
135
|
-
appendChild: function(
|
136
|
-
this.childNodes.push(
|
211
|
+
appendChild: function(o) {
|
212
|
+
this.childNodes.push(o);
|
137
213
|
}
|
138
214
|
};
|
139
|
-
for (const [
|
140
|
-
if (
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
} else if (key !== "key" && key !== "ref") {
|
152
|
-
element.setAttribute(key, String(value));
|
215
|
+
for (const [o, a] of Object.entries(s || {}))
|
216
|
+
if (o !== "children")
|
217
|
+
if (o.startsWith("on") && typeof a == "function") {
|
218
|
+
const c = o.toLowerCase().slice(2);
|
219
|
+
n.__events || (n.__events = {}), n.__events[c] = a;
|
220
|
+
} else o === "style" && typeof a == "object" ? Object.assign(n.style, a) : o === "className" ? n.setAttribute("class", String(a)) : o !== "key" && o !== "ref" && n.setAttribute(o, String(a));
|
221
|
+
const i = s == null ? void 0 : s.children;
|
222
|
+
if (i != null) {
|
223
|
+
const o = Array.isArray(i) ? i.flat() : [i];
|
224
|
+
for (const a of o) {
|
225
|
+
const c = await C(a);
|
226
|
+
n.appendChild(c);
|
153
227
|
}
|
154
228
|
}
|
155
|
-
|
156
|
-
if (children != null) {
|
157
|
-
const childArray = Array.isArray(children) ? children.flat() : [children];
|
158
|
-
for (const child of childArray) {
|
159
|
-
const childNode = await createElement(child);
|
160
|
-
element.appendChild(childNode);
|
161
|
-
}
|
162
|
-
}
|
163
|
-
return element;
|
229
|
+
return n;
|
164
230
|
}
|
165
|
-
return { nodeType: 3, textContent: String(
|
166
|
-
}
|
167
|
-
if (vnode == null) {
|
168
|
-
return document.createTextNode("");
|
231
|
+
return { nodeType: 3, textContent: String(r) };
|
169
232
|
}
|
170
|
-
if (typeof
|
233
|
+
if (r == null || typeof r == "boolean")
|
171
234
|
return document.createTextNode("");
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
const node = await createElement(child);
|
180
|
-
fragment.appendChild(node);
|
235
|
+
if (typeof r == "number" || typeof r == "string")
|
236
|
+
return document.createTextNode(String(r));
|
237
|
+
if (Array.isArray(r)) {
|
238
|
+
const e = document.createDocumentFragment();
|
239
|
+
for (const s of r) {
|
240
|
+
const n = await C(s);
|
241
|
+
e.appendChild(n);
|
181
242
|
}
|
182
|
-
return
|
243
|
+
return e;
|
183
244
|
}
|
184
|
-
if ("type" in
|
185
|
-
const { type, props } =
|
186
|
-
if (typeof
|
245
|
+
if ("type" in r && r.props !== void 0) {
|
246
|
+
const { type: e, props: s } = r;
|
247
|
+
if (typeof e == "function")
|
187
248
|
try {
|
188
|
-
const
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
}
|
193
|
-
return node;
|
194
|
-
} catch (error) {
|
195
|
-
console.error("Error rendering component:", error);
|
196
|
-
return document.createTextNode("");
|
197
|
-
}
|
198
|
-
}
|
199
|
-
const element = document.createElement(type);
|
200
|
-
for (const [key, value] of Object.entries(props || {})) {
|
201
|
-
if (key === "children") continue;
|
202
|
-
if (key.startsWith("on") && typeof value === "function") {
|
203
|
-
const eventName = key.toLowerCase().slice(2);
|
204
|
-
const existingHandler = (_a = element.__events) == null ? void 0 : _a[eventName];
|
205
|
-
if (existingHandler) {
|
206
|
-
element.removeEventListener(eventName, existingHandler);
|
207
|
-
}
|
208
|
-
element.addEventListener(eventName, value);
|
209
|
-
if (!element.__events) {
|
210
|
-
element.__events = {};
|
211
|
-
}
|
212
|
-
element.__events[eventName] = value;
|
213
|
-
} else if (key === "style" && typeof value === "object") {
|
214
|
-
Object.assign(element.style, value);
|
215
|
-
} else if (key === "className") {
|
216
|
-
element.setAttribute("class", String(value));
|
217
|
-
} else if (key !== "key" && key !== "ref") {
|
218
|
-
element.setAttribute(key, String(value));
|
249
|
+
const o = await e(s || {}), a = await C(o);
|
250
|
+
return a instanceof Element && a.setAttribute("data-component-id", e.name || e.toString()), a;
|
251
|
+
} catch (o) {
|
252
|
+
return console.error("Error rendering component:", o), document.createTextNode("");
|
219
253
|
}
|
220
|
-
|
221
|
-
const
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
254
|
+
const n = document.createElement(e);
|
255
|
+
for (const [o, a] of Object.entries(s || {}))
|
256
|
+
if (o !== "children")
|
257
|
+
if (o.startsWith("on") && typeof a == "function") {
|
258
|
+
const c = o.toLowerCase().slice(2), d = (t = n.__events) == null ? void 0 : t[c];
|
259
|
+
d && n.removeEventListener(c, d), n.addEventListener(c, a), n.__events || (n.__events = {}), n.__events[c] = a;
|
260
|
+
} else o === "style" && typeof a == "object" ? Object.assign(n.style, a) : o === "className" ? n.setAttribute("class", String(a)) : o !== "key" && o !== "ref" && n.setAttribute(o, String(a));
|
261
|
+
const i = s == null ? void 0 : s.children;
|
262
|
+
if (i != null) {
|
263
|
+
const o = Array.isArray(i) ? i.flat() : [i];
|
264
|
+
for (const a of o) {
|
265
|
+
const c = await C(a);
|
266
|
+
n.appendChild(c);
|
227
267
|
}
|
228
268
|
}
|
229
|
-
return
|
269
|
+
return n;
|
230
270
|
}
|
231
|
-
return document.createTextNode(String(
|
271
|
+
return document.createTextNode(String(r));
|
232
272
|
}
|
233
|
-
class
|
234
|
-
constructor(
|
235
|
-
this.state = {};
|
236
|
-
this.element = null;
|
237
|
-
this._mounted = false;
|
238
|
-
this.props = props;
|
273
|
+
class We {
|
274
|
+
constructor(t = {}) {
|
275
|
+
this.state = {}, this.element = null, this._mounted = !1, this.props = t;
|
239
276
|
}
|
240
277
|
componentDidMount() {
|
241
278
|
}
|
242
|
-
async setState(
|
243
|
-
const
|
244
|
-
this.state = { ...
|
245
|
-
|
246
|
-
prev: prevState,
|
279
|
+
async setState(t) {
|
280
|
+
const e = { ...this.state };
|
281
|
+
this.state = { ...e, ...t }, console.log(`${this.constructor.name} state updated:`, {
|
282
|
+
prev: e,
|
247
283
|
next: this.state
|
248
|
-
});
|
249
|
-
await Promise.resolve();
|
250
|
-
if (this._mounted) {
|
251
|
-
await this.update();
|
252
|
-
} else {
|
253
|
-
await this.update();
|
254
|
-
}
|
284
|
+
}), await Promise.resolve(), this._mounted ? await this.update() : await this.update();
|
255
285
|
}
|
256
|
-
_replayEvents(
|
257
|
-
const
|
258
|
-
Object.entries(
|
259
|
-
|
260
|
-
});
|
261
|
-
newElement.__events = oldEvents;
|
286
|
+
_replayEvents(t, e) {
|
287
|
+
const s = t.__events || {};
|
288
|
+
Object.entries(s).forEach(([n, i]) => {
|
289
|
+
e.addEventListener(n, i);
|
290
|
+
}), e.__events = s;
|
262
291
|
}
|
263
|
-
_deepCloneWithEvents(
|
264
|
-
const
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
});
|
270
|
-
Array.from(node.childNodes).forEach((child) => {
|
271
|
-
if (child instanceof HTMLElement) {
|
272
|
-
clone.appendChild(this._deepCloneWithEvents(child));
|
273
|
-
} else {
|
274
|
-
clone.appendChild(child.cloneNode(true));
|
275
|
-
}
|
276
|
-
});
|
277
|
-
return clone;
|
292
|
+
_deepCloneWithEvents(t) {
|
293
|
+
const e = t.cloneNode(!1), s = t.__events || {};
|
294
|
+
return e.__events = s, Object.entries(s).forEach(([n, i]) => {
|
295
|
+
e.addEventListener(n, i);
|
296
|
+
}), Array.from(t.childNodes).forEach((n) => {
|
297
|
+
n instanceof HTMLElement ? e.appendChild(this._deepCloneWithEvents(n)) : e.appendChild(n.cloneNode(!0));
|
298
|
+
}), e;
|
278
299
|
}
|
279
300
|
async update() {
|
280
|
-
const
|
281
|
-
if (!
|
282
|
-
const
|
283
|
-
if (
|
284
|
-
return this._updateElement(
|
285
|
-
|
286
|
-
|
287
|
-
wrapper.appendChild(rendered);
|
288
|
-
return this._updateElement(wrapper);
|
301
|
+
const t = this.render();
|
302
|
+
if (!t) return document.createTextNode("");
|
303
|
+
const e = await C(t);
|
304
|
+
if (e instanceof HTMLElement)
|
305
|
+
return this._updateElement(e);
|
306
|
+
const s = document.createElement("div");
|
307
|
+
return s.appendChild(e), this._updateElement(s);
|
289
308
|
}
|
290
|
-
async _updateElement(
|
291
|
-
const
|
292
|
-
|
293
|
-
if (!this.element) {
|
294
|
-
this.element = newElement;
|
295
|
-
if (!this._mounted) {
|
296
|
-
this._mounted = true;
|
297
|
-
queueMicrotask(() => this.componentDidMount());
|
298
|
-
}
|
299
|
-
} else if (this.element.parentNode) {
|
300
|
-
this.element.parentNode.replaceChild(newElement, this.element);
|
301
|
-
this.element = newElement;
|
302
|
-
}
|
303
|
-
return this.element;
|
309
|
+
async _updateElement(t) {
|
310
|
+
const e = this._deepCloneWithEvents(t);
|
311
|
+
return e.__instance = this, this.element ? this.element.parentNode && (this.element.parentNode.replaceChild(e, this.element), this.element = e) : (this.element = e, this._mounted || (this._mounted = !0, queueMicrotask(() => this.componentDidMount()))), this.element;
|
304
312
|
}
|
305
313
|
render() {
|
306
314
|
throw new Error("Component must implement render() method");
|
307
315
|
}
|
308
316
|
}
|
309
|
-
let
|
310
|
-
const
|
311
|
-
function
|
312
|
-
if (
|
313
|
-
|
317
|
+
let H = !1;
|
318
|
+
const X = [];
|
319
|
+
function ce(r) {
|
320
|
+
if (H) {
|
321
|
+
X.push(r);
|
314
322
|
return;
|
315
323
|
}
|
316
|
-
|
324
|
+
H = !0;
|
317
325
|
try {
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
nextFn == null ? void 0 : nextFn();
|
326
|
+
for (r(); X.length > 0; ) {
|
327
|
+
const t = X.shift();
|
328
|
+
t == null || t();
|
322
329
|
}
|
323
330
|
} finally {
|
324
|
-
|
331
|
+
H = !1;
|
325
332
|
}
|
326
333
|
}
|
327
|
-
let
|
328
|
-
const
|
329
|
-
|
330
|
-
const
|
331
|
-
|
332
|
-
|
333
|
-
let globalRenderCallback = null;
|
334
|
-
let globalContainer = null;
|
335
|
-
let currentElement = null;
|
336
|
-
const isServer = typeof window === "undefined";
|
337
|
-
const serverStates = /* @__PURE__ */ new Map();
|
338
|
-
function setRenderCallback(callback, element, container) {
|
339
|
-
globalRenderCallback = callback;
|
340
|
-
globalContainer = container;
|
341
|
-
currentElement = element;
|
334
|
+
let u = 0;
|
335
|
+
const Z = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map(), L = /* @__PURE__ */ new Map(), K = /* @__PURE__ */ new Map(), ee = /* @__PURE__ */ new Map();
|
336
|
+
let ne = null, oe = null, ie = null;
|
337
|
+
const ve = typeof window > "u", W = /* @__PURE__ */ new Map();
|
338
|
+
function Se(r, t, e) {
|
339
|
+
ne = r, oe = e, ie = t;
|
342
340
|
}
|
343
|
-
function
|
344
|
-
|
345
|
-
stateIndices.set(currentRender, 0);
|
346
|
-
return currentRender;
|
341
|
+
function U() {
|
342
|
+
return u++, b.set(u, 0), u;
|
347
343
|
}
|
348
|
-
function
|
349
|
-
|
350
|
-
serverStates.delete(currentRender);
|
351
|
-
}
|
352
|
-
currentRender = 0;
|
344
|
+
function q() {
|
345
|
+
ve && W.delete(u), u = 0;
|
353
346
|
}
|
354
|
-
function
|
355
|
-
if (!
|
347
|
+
function Ae(r) {
|
348
|
+
if (!u)
|
356
349
|
throw new Error("useState must be called within a render");
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
const componentState = serverStates.get(currentRender);
|
363
|
-
const index22 = stateIndices.get(currentRender) || 0;
|
364
|
-
if (!componentState.has(index22)) {
|
365
|
-
componentState.set(index22, initial);
|
366
|
-
}
|
367
|
-
const state2 = componentState.get(index22);
|
368
|
-
const setState2 = (newValue) => {
|
350
|
+
if (ve) {
|
351
|
+
W.has(u) || W.set(u, /* @__PURE__ */ new Map());
|
352
|
+
const i = W.get(u), o = b.get(u) || 0;
|
353
|
+
i.has(o) || i.set(o, r);
|
354
|
+
const a = i.get(o), c = (d) => {
|
369
355
|
};
|
370
|
-
|
371
|
-
return [state2, setState2];
|
356
|
+
return b.set(u, o + 1), [a, c];
|
372
357
|
}
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
const
|
377
|
-
|
378
|
-
|
379
|
-
componentStates.push(initial);
|
380
|
-
}
|
381
|
-
const state = componentStates[index2];
|
382
|
-
const setState = (newValue) => {
|
383
|
-
const nextValue = typeof newValue === "function" ? newValue(componentStates[index2]) : newValue;
|
384
|
-
if (componentStates[index2] === nextValue) return;
|
385
|
-
componentStates[index2] = nextValue;
|
386
|
-
if (isBatching) {
|
387
|
-
batchUpdates(() => rerender(currentRender));
|
388
|
-
} else {
|
389
|
-
rerender(currentRender);
|
390
|
-
}
|
358
|
+
Z.has(u) || Z.set(u, []);
|
359
|
+
const t = Z.get(u), e = b.get(u);
|
360
|
+
e >= t.length && t.push(r);
|
361
|
+
const s = t[e], n = (i) => {
|
362
|
+
const o = typeof i == "function" ? i(t[e]) : i;
|
363
|
+
t[e] !== o && (t[e] = o, H ? ce(() => pe(u)) : pe(u));
|
391
364
|
};
|
392
|
-
|
393
|
-
return [state, setState];
|
365
|
+
return b.set(u, e + 1), [s, n];
|
394
366
|
}
|
395
|
-
function
|
396
|
-
if (!
|
397
|
-
const
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
if (prevEffect == null ? void 0 : prevEffect.cleanup) {
|
405
|
-
prevEffect.cleanup();
|
406
|
-
}
|
407
|
-
queueMicrotask(() => {
|
408
|
-
const cleanup = callback() || void 0;
|
409
|
-
componentEffects[effectIndex] = { cleanup, deps };
|
410
|
-
});
|
411
|
-
}
|
412
|
-
stateIndices.set(currentRender, effectIndex + 1);
|
367
|
+
function Ue(r, t) {
|
368
|
+
if (!u) throw new Error("useEffect must be called within a render");
|
369
|
+
const e = b.get(u);
|
370
|
+
L.has(u) || L.set(u, []);
|
371
|
+
const s = L.get(u), n = s[e];
|
372
|
+
(!n || !t || !n.deps || t.some((i, o) => i !== n.deps[o])) && (n != null && n.cleanup && n.cleanup(), queueMicrotask(() => {
|
373
|
+
const i = r() || void 0;
|
374
|
+
s[e] = { cleanup: i, deps: t };
|
375
|
+
})), b.set(u, e + 1);
|
413
376
|
}
|
414
|
-
function
|
415
|
-
if (!
|
416
|
-
const
|
417
|
-
|
418
|
-
|
377
|
+
function qe(r, t) {
|
378
|
+
if (!u) throw new Error("useMemo must be called within a render");
|
379
|
+
const e = b.get(u);
|
380
|
+
K.has(u) || K.set(u, []);
|
381
|
+
const s = K.get(u), n = s[e];
|
382
|
+
if (!n || t && t.some((i, o) => !Object.is(i, n.deps[o]))) {
|
383
|
+
const i = r();
|
384
|
+
return s[e] = { value: i, deps: t }, b.set(u, e + 1), i;
|
419
385
|
}
|
420
|
-
|
421
|
-
const prevMemo = componentMemos[memoIndex];
|
422
|
-
if (!prevMemo || deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i]))) {
|
423
|
-
const value = factory();
|
424
|
-
componentMemos[memoIndex] = { value, deps };
|
425
|
-
stateIndices.set(currentRender, memoIndex + 1);
|
426
|
-
return value;
|
427
|
-
}
|
428
|
-
stateIndices.set(currentRender, memoIndex + 1);
|
429
|
-
return prevMemo.value;
|
386
|
+
return b.set(u, e + 1), n.value;
|
430
387
|
}
|
431
|
-
function
|
432
|
-
if (!
|
433
|
-
const
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
const ref2 = { current: initial };
|
440
|
-
componentRefs.push(ref2);
|
441
|
-
stateIndices.set(currentRender, refIndex + 1);
|
442
|
-
return ref2;
|
388
|
+
function Ge(r) {
|
389
|
+
if (!u) throw new Error("useRef must be called within a render");
|
390
|
+
const t = b.get(u);
|
391
|
+
ee.has(u) || ee.set(u, []);
|
392
|
+
const e = ee.get(u);
|
393
|
+
if (t >= e.length) {
|
394
|
+
const n = { current: r };
|
395
|
+
return e.push(n), b.set(u, t + 1), n;
|
443
396
|
}
|
444
|
-
const
|
445
|
-
|
446
|
-
return ref;
|
397
|
+
const s = e[t];
|
398
|
+
return b.set(u, t + 1), s;
|
447
399
|
}
|
448
|
-
async function
|
400
|
+
async function pe(r) {
|
449
401
|
try {
|
450
|
-
const
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
}
|
457
|
-
if (globalRenderCallback && globalContainer && currentElement) {
|
458
|
-
await globalRenderCallback(currentElement, globalContainer);
|
459
|
-
}
|
460
|
-
} catch (error) {
|
461
|
-
console.error("Error during rerender:", error);
|
402
|
+
const t = L.get(r);
|
403
|
+
t && (t.forEach((e) => {
|
404
|
+
e.cleanup && e.cleanup();
|
405
|
+
}), L.set(r, [])), ne && oe && ie && await ne(ie, oe);
|
406
|
+
} catch (t) {
|
407
|
+
console.error("Error during rerender:", t);
|
462
408
|
}
|
463
409
|
}
|
464
|
-
function
|
465
|
-
const [
|
466
|
-
return [
|
410
|
+
function Je() {
|
411
|
+
const [r, t] = Ae(null);
|
412
|
+
return [r, () => t(null)];
|
467
413
|
}
|
468
|
-
let
|
469
|
-
async function
|
470
|
-
|
414
|
+
let G = !1;
|
415
|
+
async function Qe(r, t) {
|
416
|
+
G = !0;
|
471
417
|
try {
|
472
|
-
await
|
418
|
+
await ue(r, t);
|
473
419
|
} finally {
|
474
|
-
|
420
|
+
G = !1;
|
475
421
|
}
|
476
422
|
}
|
477
|
-
async function
|
478
|
-
console.log("Rendering to:",
|
479
|
-
|
480
|
-
const rendererId = prepareRender();
|
423
|
+
async function ue(r, t) {
|
424
|
+
console.log("Rendering to:", t.id || "unnamed-container"), ce(async () => {
|
425
|
+
const e = U();
|
481
426
|
try {
|
482
|
-
|
483
|
-
const
|
484
|
-
|
485
|
-
container.innerHTML = "";
|
486
|
-
}
|
487
|
-
if (isHydrating && container.firstChild) {
|
488
|
-
console.log("Hydrating existing DOM");
|
489
|
-
} else {
|
490
|
-
container.appendChild(domNode);
|
491
|
-
}
|
427
|
+
Se(ue, r, t);
|
428
|
+
const s = await C(r);
|
429
|
+
G || (t.innerHTML = ""), G && t.firstChild ? console.log("Hydrating existing DOM") : t.appendChild(s);
|
492
430
|
} finally {
|
493
|
-
|
431
|
+
q();
|
494
432
|
}
|
495
433
|
});
|
496
434
|
}
|
497
|
-
async function
|
498
|
-
|
499
|
-
|
500
|
-
}, element, null);
|
435
|
+
async function P(r) {
|
436
|
+
U(), Se(() => {
|
437
|
+
}, r, null);
|
501
438
|
try {
|
502
|
-
if (
|
503
|
-
if (typeof
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
if (
|
508
|
-
const
|
509
|
-
|
510
|
-
}
|
511
|
-
if ("type" in element && element.props !== void 0) {
|
512
|
-
const { type, props } = element;
|
513
|
-
if (typeof type === "function") {
|
439
|
+
if (r == null || typeof r == "boolean") return "";
|
440
|
+
if (typeof r == "number" || typeof r == "string")
|
441
|
+
return V(String(r));
|
442
|
+
if (Array.isArray(r))
|
443
|
+
return (await Promise.all(r.map(P))).join("");
|
444
|
+
if ("type" in r && r.props !== void 0) {
|
445
|
+
const { type: t, props: e } = r;
|
446
|
+
if (typeof t == "function")
|
514
447
|
try {
|
515
|
-
|
516
|
-
const
|
517
|
-
|
518
|
-
|
519
|
-
return
|
520
|
-
} catch (error) {
|
521
|
-
console.error("Error rendering component:", error);
|
522
|
-
return "";
|
448
|
+
U();
|
449
|
+
const i = await t(e || {}), o = await P(i);
|
450
|
+
return q(), o;
|
451
|
+
} catch (i) {
|
452
|
+
return console.error("Error rendering component:", i), "";
|
523
453
|
}
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
const renderedChildren = await Promise.all(children.map(renderToString));
|
529
|
-
return renderedChildren.join("");
|
454
|
+
if (t === Symbol.for("react.fragment") || t.name === "Fragment") {
|
455
|
+
if (e.children) {
|
456
|
+
const i = Array.isArray(e.children) ? e.children : [e.children];
|
457
|
+
return (await Promise.all(i.map(P))).join("");
|
530
458
|
}
|
531
459
|
return "";
|
532
460
|
}
|
533
|
-
let
|
534
|
-
for (const [
|
535
|
-
|
536
|
-
|
537
|
-
html += ` class="${escapeHtml(String(value))}"`;
|
538
|
-
} else if (key === "style" && typeof value === "object") {
|
539
|
-
html += ` style="${stringifyStyle(value || {})}"`;
|
540
|
-
} else if (!key.startsWith("on")) {
|
541
|
-
html += ` ${key}="${escapeHtml(String(value))}"`;
|
542
|
-
}
|
543
|
-
}
|
544
|
-
const voidElements = /* @__PURE__ */ new Set([
|
461
|
+
let s = `<${t}`;
|
462
|
+
for (const [i, o] of Object.entries(e || {}))
|
463
|
+
i === "children" || i === "key" || (i === "className" ? s += ` class="${V(String(o))}"` : i === "style" && typeof o == "object" ? s += ` style="${Ye(o || {})}"` : i.startsWith("on") || (s += ` ${i}="${V(String(o))}"`));
|
464
|
+
if ((/* @__PURE__ */ new Set([
|
545
465
|
"area",
|
546
466
|
"base",
|
547
467
|
"br",
|
@@ -556,44 +476,53 @@ async function renderToString(element) {
|
|
556
476
|
"source",
|
557
477
|
"track",
|
558
478
|
"wbr"
|
559
|
-
])
|
560
|
-
|
561
|
-
|
479
|
+
])).has(t))
|
480
|
+
return s + "/>";
|
481
|
+
if (s += ">", e != null && e.children) {
|
482
|
+
const i = Array.isArray(e.children) ? e.children : [e.children];
|
483
|
+
for (const o of i)
|
484
|
+
s += await P(o);
|
562
485
|
}
|
563
|
-
|
564
|
-
if (props == null ? void 0 : props.children) {
|
565
|
-
const children = Array.isArray(props.children) ? props.children : [props.children];
|
566
|
-
for (const child of children) {
|
567
|
-
html += await renderToString(child);
|
568
|
-
}
|
569
|
-
}
|
570
|
-
return html + `</${type}>`;
|
486
|
+
return s + `</${t}>`;
|
571
487
|
}
|
572
|
-
return
|
488
|
+
return V(String(r));
|
573
489
|
} finally {
|
574
|
-
|
490
|
+
q();
|
575
491
|
}
|
576
492
|
}
|
577
|
-
function
|
578
|
-
return
|
493
|
+
function V(r) {
|
494
|
+
return r.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
495
|
+
}
|
496
|
+
function Ye(r) {
|
497
|
+
return Object.entries(r).map(([t, e]) => `${ze(t)}:${e}`).join(";");
|
579
498
|
}
|
580
|
-
function
|
581
|
-
return
|
499
|
+
function ze(r) {
|
500
|
+
return r.replace(/[A-Z]/g, (t) => "-" + t.toLowerCase());
|
501
|
+
}
|
502
|
+
function Xe(r) {
|
503
|
+
const t = {
|
504
|
+
_currentValue: r,
|
505
|
+
Provider: function({ value: s, children: n }) {
|
506
|
+
return t._currentValue = s, n;
|
507
|
+
},
|
508
|
+
Consumer: function({ children: s }) {
|
509
|
+
return s(t._currentValue);
|
510
|
+
}
|
511
|
+
};
|
512
|
+
return t;
|
582
513
|
}
|
583
|
-
function
|
584
|
-
return
|
514
|
+
function Ze(r) {
|
515
|
+
return r._currentValue;
|
585
516
|
}
|
586
|
-
class
|
517
|
+
class xe {
|
587
518
|
// Renamed from isConnected to _connected
|
588
|
-
constructor(
|
589
|
-
this.connection = null
|
590
|
-
this._connected = false;
|
591
|
-
this.options = {
|
519
|
+
constructor(t) {
|
520
|
+
this.connection = null, this._connected = !1, this.options = {
|
592
521
|
retryAttempts: 3,
|
593
522
|
retryDelay: 1e3,
|
594
523
|
connectionTimeout: 1e4,
|
595
|
-
autoIndex:
|
596
|
-
...
|
524
|
+
autoIndex: !0,
|
525
|
+
...t
|
597
526
|
};
|
598
527
|
}
|
599
528
|
/**
|
@@ -601,56 +530,38 @@ class DatabaseConnector {
|
|
601
530
|
*/
|
602
531
|
async connect() {
|
603
532
|
try {
|
604
|
-
if (this._connected && this.connection)
|
533
|
+
if (this._connected && this.connection)
|
605
534
|
return this.connection;
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
while (attempts < (this.options.retryAttempts || 3)) {
|
535
|
+
$.set("strictQuery", !0);
|
536
|
+
let t = 0;
|
537
|
+
for (; t < (this.options.retryAttempts || 3); )
|
610
538
|
try {
|
611
|
-
await
|
539
|
+
await $.connect(this.options.uri, {
|
612
540
|
dbName: this.options.name,
|
613
541
|
connectTimeoutMS: this.options.connectionTimeout,
|
614
542
|
autoIndex: this.options.autoIndex,
|
615
543
|
...this.options.options
|
616
544
|
});
|
617
545
|
break;
|
618
|
-
} catch (
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
}
|
623
|
-
console.log(`Connection attempt ${attempts} failed. Retrying in ${this.options.retryDelay}ms...`);
|
624
|
-
await new Promise((resolve) => setTimeout(resolve, this.options.retryDelay));
|
546
|
+
} catch (e) {
|
547
|
+
if (t++, t >= (this.options.retryAttempts || 3))
|
548
|
+
throw e;
|
549
|
+
console.log(`Connection attempt ${t} failed. Retrying in ${this.options.retryDelay}ms...`), await new Promise((s) => setTimeout(s, this.options.retryDelay));
|
625
550
|
}
|
626
|
-
}
|
627
|
-
|
628
|
-
this.
|
629
|
-
|
630
|
-
this.connection
|
631
|
-
|
632
|
-
|
633
|
-
});
|
634
|
-
this.connection.on("disconnected", () => {
|
635
|
-
console.log("MongoDB disconnected");
|
636
|
-
this._connected = false;
|
637
|
-
});
|
638
|
-
return this.connection;
|
639
|
-
} catch (error) {
|
640
|
-
console.error("Failed to connect to MongoDB:", error);
|
641
|
-
throw error;
|
551
|
+
return this.connection = $.connection, this._connected = !0, console.log(`Connected to MongoDB at ${this.options.uri}/${this.options.name}`), this.connection.on("error", (e) => {
|
552
|
+
console.error("MongoDB connection error:", e), this._connected = !1;
|
553
|
+
}), this.connection.on("disconnected", () => {
|
554
|
+
console.log("MongoDB disconnected"), this._connected = !1;
|
555
|
+
}), this.connection;
|
556
|
+
} catch (t) {
|
557
|
+
throw console.error("Failed to connect to MongoDB:", t), t;
|
642
558
|
}
|
643
559
|
}
|
644
560
|
/**
|
645
561
|
* Disconnect from the database
|
646
562
|
*/
|
647
563
|
async disconnect() {
|
648
|
-
|
649
|
-
await mongoose.disconnect();
|
650
|
-
this._connected = false;
|
651
|
-
this.connection = null;
|
652
|
-
console.log("Disconnected from MongoDB");
|
653
|
-
}
|
564
|
+
this.connection && (await $.disconnect(), this._connected = !1, this.connection = null, console.log("Disconnected from MongoDB"));
|
654
565
|
}
|
655
566
|
/**
|
656
567
|
* Check if connected to the database
|
@@ -665,165 +576,105 @@ class DatabaseConnector {
|
|
665
576
|
return this.connection;
|
666
577
|
}
|
667
578
|
}
|
668
|
-
function
|
669
|
-
const
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
}
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
}));
|
579
|
+
function Ke(r = {}) {
|
580
|
+
const t = O(), {
|
581
|
+
port: e = 3e3,
|
582
|
+
staticDir: s = "public",
|
583
|
+
enableCors: n = !0,
|
584
|
+
apiPrefix: i = "/api",
|
585
|
+
ssrEnabled: o = !0,
|
586
|
+
middlewares: a = [],
|
587
|
+
enableCompression: c = !0,
|
588
|
+
enableHelmet: d = !0,
|
589
|
+
logFormat: h = "dev",
|
590
|
+
trustProxy: E = !1,
|
591
|
+
showErrorDetails: S = w.env.NODE_ENV !== "production"
|
592
|
+
} = r;
|
593
|
+
if (E && t.set("trust proxy", E), t.use(O.json()), t.use(O.urlencoded({ extended: !0 })), c && t.use(Ne()), d && t.use(Oe({
|
594
|
+
contentSecurityPolicy: r.disableCSP ? !1 : void 0
|
595
|
+
})), h && t.use(Pe(h)), n && t.use((l, p, f) => {
|
596
|
+
if (p.header("Access-Control-Allow-Origin", "*"), p.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"), p.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"), l.method === "OPTIONS")
|
597
|
+
return p.sendStatus(200);
|
598
|
+
f();
|
599
|
+
}), a.forEach((l) => t.use(l)), s) {
|
600
|
+
const l = de.resolve(w.cwd(), s);
|
601
|
+
De.existsSync(l) ? (t.use(O.static(l, {
|
602
|
+
maxAge: r.staticCacheAge || "1d",
|
603
|
+
etag: !0
|
604
|
+
})), console.log(`📂 Serving static files from: ${l}`)) : console.warn(`⚠️ Static directory not found: ${l}`);
|
695
605
|
}
|
696
|
-
|
697
|
-
|
698
|
-
}
|
699
|
-
if (enableCors) {
|
700
|
-
app.use((req, res, next) => {
|
701
|
-
res.header("Access-Control-Allow-Origin", "*");
|
702
|
-
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
703
|
-
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
|
704
|
-
if (req.method === "OPTIONS") {
|
705
|
-
return res.sendStatus(200);
|
706
|
-
}
|
707
|
-
next();
|
708
|
-
});
|
709
|
-
}
|
710
|
-
middlewares.forEach((middleware) => app.use(middleware));
|
711
|
-
if (staticDir) {
|
712
|
-
const staticPath = path.resolve(process.cwd(), staticDir);
|
713
|
-
if (fs.existsSync(staticPath)) {
|
714
|
-
app.use(express.static(staticPath, {
|
715
|
-
maxAge: options.staticCacheAge || "1d",
|
716
|
-
etag: true
|
717
|
-
}));
|
718
|
-
console.log(`📂 Serving static files from: ${staticPath}`);
|
719
|
-
} else {
|
720
|
-
console.warn(`⚠️ Static directory not found: ${staticPath}`);
|
721
|
-
}
|
722
|
-
}
|
723
|
-
let dbConnector = null;
|
724
|
-
app.connectToDatabase = async (dbOptions) => {
|
606
|
+
let y = null;
|
607
|
+
t.connectToDatabase = async (l) => {
|
725
608
|
try {
|
726
|
-
|
727
|
-
console.log("
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
await dbConnector.connect();
|
732
|
-
console.log("✅ Database connected successfully");
|
733
|
-
process.on("SIGTERM", async () => {
|
734
|
-
if (dbConnector && dbConnector.isConnected()) {
|
735
|
-
await dbConnector.disconnect();
|
736
|
-
console.log("Database connection closed");
|
737
|
-
}
|
738
|
-
});
|
739
|
-
return dbConnector;
|
740
|
-
} catch (error) {
|
741
|
-
console.error("❌ Failed to connect to database:", error);
|
742
|
-
throw error;
|
609
|
+
return y && y.isConnected() ? (console.log("✅ Using existing database connection"), y) : (y = new xe(l), await y.connect(), console.log("✅ Database connected successfully"), w.on("SIGTERM", async () => {
|
610
|
+
y && y.isConnected() && (await y.disconnect(), console.log("Database connection closed"));
|
611
|
+
}), y);
|
612
|
+
} catch (p) {
|
613
|
+
throw console.error("❌ Failed to connect to database:", p), p;
|
743
614
|
}
|
744
615
|
};
|
745
|
-
const
|
746
|
-
|
747
|
-
app.registerApi = (routePath, router, routerOptions = {}) => {
|
616
|
+
const I = {}, J = {};
|
617
|
+
return t.registerApi = (l, p, f = {}) => {
|
748
618
|
try {
|
749
|
-
const { prefix =
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
console.log(`🔌 API registered: ${fullPath}`);
|
754
|
-
} catch (error) {
|
755
|
-
console.error(`❌ Failed to register API at ${routePath}:`, error);
|
619
|
+
const { prefix: g = i } = f, T = de.posix.join(g, l).replace(/\\/g, "/");
|
620
|
+
t.use(T, p), I[T] = { router: p, options: f }, console.log(`🔌 API registered: ${T}`);
|
621
|
+
} catch (g) {
|
622
|
+
console.error(`❌ Failed to register API at ${l}:`, g);
|
756
623
|
}
|
757
|
-
return
|
758
|
-
}
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
req,
|
772
|
-
res,
|
773
|
-
params: req.params,
|
774
|
-
query: req.query,
|
775
|
-
user: req.user,
|
776
|
-
...options2.props
|
777
|
-
};
|
778
|
-
const html = await renderToString(component(props));
|
779
|
-
res.send(`
|
624
|
+
return t;
|
625
|
+
}, t.registerSSR = (l, p, f = {}) => o ? (J[l] = { component: p, options: f }, t.get(l, async (g, T, Q) => {
|
626
|
+
try {
|
627
|
+
if (g.query.nossr === "true")
|
628
|
+
return Q();
|
629
|
+
const Y = {
|
630
|
+
req: g,
|
631
|
+
res: T,
|
632
|
+
params: g.params,
|
633
|
+
query: g.query,
|
634
|
+
user: g.user,
|
635
|
+
...f.props
|
636
|
+
}, _e = await P(p(Y));
|
637
|
+
T.send(`
|
780
638
|
<!DOCTYPE html>
|
781
|
-
<html lang="${
|
639
|
+
<html lang="${f.lang || "en"}">
|
782
640
|
<head>
|
783
641
|
<meta charset="UTF-8">
|
784
642
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
785
|
-
<title>${
|
786
|
-
${
|
787
|
-
|
788
|
-
${
|
789
|
-
${
|
643
|
+
<title>${f.title || "Frontend Hamroun App"}</title>
|
644
|
+
${f.meta ? f.meta.map((F) => `<meta ${Object.entries(F).map(([Ie, Re]) => `${Ie}="${Re}"`).join(" ")}>`).join(`
|
645
|
+
`) : ""}
|
646
|
+
${f.head || ""}
|
647
|
+
${f.styles ? `<style>${f.styles}</style>` : ""}
|
648
|
+
${f.styleSheets ? f.styleSheets.map((F) => `<link rel="stylesheet" href="${F}">`).join(`
|
649
|
+
`) : ""}
|
790
650
|
</head>
|
791
|
-
<body ${
|
792
|
-
<div id="${
|
651
|
+
<body ${f.bodyAttributes || ""}>
|
652
|
+
<div id="${f.rootId || "root"}">${_e}</div>
|
793
653
|
<script>
|
794
|
-
window.__INITIAL_DATA__ = ${JSON.stringify(
|
654
|
+
window.__INITIAL_DATA__ = ${JSON.stringify(f.initialData || {})};
|
795
655
|
<\/script>
|
796
|
-
${
|
656
|
+
${f.scripts ? f.scripts.map((F) => `<script src="${F}"><\/script>`).join(`
|
657
|
+
`) : ""}
|
797
658
|
</body>
|
798
659
|
</html>
|
799
660
|
`);
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
const statusCode = err.statusCode || err.status || 500;
|
814
|
-
const isApiRequest = req.path.startsWith(apiPrefix);
|
815
|
-
if (isApiRequest) {
|
816
|
-
res.status(statusCode).json({
|
817
|
-
success: false,
|
818
|
-
error: showErrorDetails ? err.message : "Internal Server Error",
|
819
|
-
stack: showErrorDetails ? err.stack : void 0
|
820
|
-
});
|
821
|
-
} else {
|
822
|
-
res.status(statusCode).send(`
|
661
|
+
} catch (Y) {
|
662
|
+
if (console.error("SSR Error:", Y), f.fallback)
|
663
|
+
return Q();
|
664
|
+
T.status(500).send("Server rendering error");
|
665
|
+
}
|
666
|
+
}), console.log(`🖥️ SSR registered: ${l}`), t) : (console.log(`⚠️ SSR disabled: skipping registration of ${l}`), t), t.use((l, p, f, g) => {
|
667
|
+
console.error("Server error:", l);
|
668
|
+
const T = l.statusCode || l.status || 500;
|
669
|
+
p.path.startsWith(i) ? f.status(T).json({
|
670
|
+
success: !1,
|
671
|
+
error: S ? l.message : "Internal Server Error",
|
672
|
+
stack: S ? l.stack : void 0
|
673
|
+
}) : f.status(T).send(`
|
823
674
|
<!DOCTYPE html>
|
824
675
|
<html>
|
825
676
|
<head>
|
826
|
-
<title>Error - ${
|
677
|
+
<title>Error - ${T}</title>
|
827
678
|
<style>
|
828
679
|
body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }
|
829
680
|
.error { background: #f8d7da; border: 1px solid #f5c6cb; padding: 1rem; border-radius: 4px; }
|
@@ -831,20 +682,14 @@ function createServer(options = {}) {
|
|
831
682
|
</style>
|
832
683
|
</head>
|
833
684
|
<body>
|
834
|
-
<h1>Error ${
|
835
|
-
<div class="error">${
|
836
|
-
${
|
685
|
+
<h1>Error ${T}</h1>
|
686
|
+
<div class="error">${S ? l.message : "Internal Server Error"}</div>
|
687
|
+
${S && l.stack ? `<pre class="stack">${l.stack}</pre>` : ""}
|
837
688
|
</body>
|
838
689
|
</html>
|
839
690
|
`);
|
840
|
-
|
841
|
-
|
842
|
-
app.use((req, res) => {
|
843
|
-
const isApiRequest = req.path.startsWith(apiPrefix);
|
844
|
-
if (isApiRequest) {
|
845
|
-
res.status(404).json({ success: false, error: "Not Found" });
|
846
|
-
} else {
|
847
|
-
res.status(404).send(`
|
691
|
+
}), t.use((l, p) => {
|
692
|
+
l.path.startsWith(i) ? p.status(404).json({ success: !1, error: "Not Found" }) : p.status(404).send(`
|
848
693
|
<!DOCTYPE html>
|
849
694
|
<html>
|
850
695
|
<head>
|
@@ -860,521 +705,262 @@ function createServer(options = {}) {
|
|
860
705
|
</body>
|
861
706
|
</html>
|
862
707
|
`);
|
863
|
-
|
864
|
-
|
865
|
-
app.start = (callback) => {
|
866
|
-
const server = app.listen(port, () => {
|
708
|
+
}), t.start = (l) => {
|
709
|
+
const p = t.listen(e, () => {
|
867
710
|
console.log(`
|
868
|
-
🚀 Frontend Hamroun server running at http://localhost:${
|
869
|
-
${Object.keys(
|
711
|
+
🚀 Frontend Hamroun server running at http://localhost:${e}
|
712
|
+
${Object.keys(I).length > 0 ? `
|
870
713
|
📡 Registered API Routes:
|
871
|
-
${Object.keys(
|
872
|
-
|
714
|
+
${Object.keys(I).map((g) => ` ${g}`).join(`
|
715
|
+
`)}` : ""}
|
716
|
+
${Object.keys(J).length > 0 ? `
|
873
717
|
🖥️ Registered SSR Routes:
|
874
|
-
${Object.keys(
|
875
|
-
|
876
|
-
|
877
|
-
})
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
console.
|
882
|
-
if (dbConnector && dbConnector.isConnected()) {
|
883
|
-
await dbConnector.disconnect();
|
884
|
-
console.log("Database connection closed");
|
885
|
-
}
|
886
|
-
process.exit(0);
|
887
|
-
});
|
888
|
-
setTimeout(() => {
|
889
|
-
console.error("Could not close connections in time, forcefully shutting down");
|
890
|
-
process.exit(1);
|
718
|
+
${Object.keys(J).map((g) => ` ${g}`).join(`
|
719
|
+
`)}` : ""}
|
720
|
+
`), l && l();
|
721
|
+
}), f = async (g) => {
|
722
|
+
console.log(`${g} signal received: closing HTTP server and cleaning up`), p.close(async () => {
|
723
|
+
console.log("HTTP server closed"), y && y.isConnected() && (await y.disconnect(), console.log("Database connection closed")), w.exit(0);
|
724
|
+
}), setTimeout(() => {
|
725
|
+
console.error("Could not close connections in time, forcefully shutting down"), w.exit(1);
|
891
726
|
}, 1e4);
|
892
727
|
};
|
893
|
-
|
894
|
-
|
895
|
-
return server;
|
896
|
-
};
|
897
|
-
return app;
|
898
|
-
}
|
899
|
-
const defaultErrorHandler = (error, { res }) => {
|
900
|
-
console.error("API Error:", error);
|
901
|
-
const status = error.status || error.statusCode || 500;
|
902
|
-
const message = error.message || "Internal server error";
|
903
|
-
res.status(status).json({
|
904
|
-
success: false,
|
905
|
-
error: message,
|
906
|
-
stack: process.env.NODE_ENV !== "production" ? error.stack : void 0
|
907
|
-
});
|
908
|
-
};
|
909
|
-
function createModelRouter(model, options = {}) {
|
910
|
-
const router = express.Router();
|
911
|
-
const { middleware = [], errorHandler = defaultErrorHandler } = options;
|
912
|
-
middleware.forEach((mw) => router.use(mw));
|
913
|
-
const handleRoute = (handler) => async (req, res, next) => {
|
914
|
-
try {
|
915
|
-
const context = { req, res, next, params: req.params, query: req.query, body: req.body };
|
916
|
-
return await handler(context);
|
917
|
-
} catch (error) {
|
918
|
-
const context = { req, res, next, params: req.params, query: req.query, body: req.body };
|
919
|
-
return errorHandler(error, context);
|
920
|
-
}
|
921
|
-
};
|
922
|
-
router.get("/", handleRoute(async ({ req, res }) => {
|
923
|
-
const paginationOptions = req.pagination || { page: 1, limit: 10 };
|
924
|
-
const result = await model.getAll(paginationOptions);
|
925
|
-
res.json({
|
926
|
-
success: true,
|
927
|
-
...result
|
928
|
-
});
|
929
|
-
}));
|
930
|
-
router.get("/:id", handleRoute(async ({ params, res }) => {
|
931
|
-
const item = await model.getById(params.id);
|
932
|
-
if (!item) {
|
933
|
-
res.status(404).json({
|
934
|
-
success: false,
|
935
|
-
error: "Item not found"
|
936
|
-
});
|
937
|
-
return;
|
938
|
-
}
|
939
|
-
res.json({
|
940
|
-
success: true,
|
941
|
-
data: item
|
942
|
-
});
|
943
|
-
}));
|
944
|
-
router.post("/", handleRoute(async ({ body, res }) => {
|
945
|
-
const newItem = await model.create(body);
|
946
|
-
res.status(201).json({
|
947
|
-
success: true,
|
948
|
-
data: newItem,
|
949
|
-
message: "Item created successfully"
|
950
|
-
});
|
951
|
-
}));
|
952
|
-
router.put("/:id", handleRoute(async ({ params, body, res }) => {
|
953
|
-
const updatedItem = await model.update(params.id, body);
|
954
|
-
if (!updatedItem) {
|
955
|
-
res.status(404).json({
|
956
|
-
success: false,
|
957
|
-
error: "Item not found"
|
958
|
-
});
|
959
|
-
return;
|
960
|
-
}
|
961
|
-
res.json({
|
962
|
-
success: true,
|
963
|
-
data: updatedItem,
|
964
|
-
message: "Item updated successfully"
|
965
|
-
});
|
966
|
-
}));
|
967
|
-
router.delete("/:id", handleRoute(async ({ params, res }) => {
|
968
|
-
const success = await model.delete(params.id);
|
969
|
-
if (!success) {
|
970
|
-
res.status(404).json({
|
971
|
-
success: false,
|
972
|
-
error: "Item not found"
|
973
|
-
});
|
974
|
-
return;
|
975
|
-
}
|
976
|
-
res.json({
|
977
|
-
success: true,
|
978
|
-
message: "Item deleted successfully"
|
979
|
-
});
|
980
|
-
}));
|
981
|
-
return router;
|
982
|
-
}
|
983
|
-
function createApiRouter$1(routeConfig, options = {}) {
|
984
|
-
const router = express.Router();
|
985
|
-
const { middleware = [], errorHandler = defaultErrorHandler } = options;
|
986
|
-
middleware.forEach((mw) => router.use(mw));
|
987
|
-
const handleRoute = (handler) => async (req, res, next) => {
|
988
|
-
try {
|
989
|
-
const context = { req, res, next, params: req.params, query: req.query, body: req.body };
|
990
|
-
if (res.headersSent) {
|
991
|
-
return;
|
992
|
-
}
|
993
|
-
return await handler(context);
|
994
|
-
} catch (error) {
|
995
|
-
if (res.headersSent) {
|
996
|
-
console.error("Error occurred after response was sent:", error);
|
997
|
-
return;
|
998
|
-
}
|
999
|
-
const context = { req, res, next, params: req.params, query: req.query, body: req.body };
|
1000
|
-
return errorHandler(error, context);
|
1001
|
-
}
|
1002
|
-
};
|
1003
|
-
Object.entries(routeConfig).forEach(([path2, config]) => {
|
1004
|
-
const { method, handler } = config;
|
1005
|
-
router[method](path2, handleRoute(handler));
|
1006
|
-
});
|
1007
|
-
return router;
|
1008
|
-
}
|
1009
|
-
function apiResponse(success, data, message, error, meta) {
|
1010
|
-
const response = { success };
|
1011
|
-
if (data !== void 0) response.data = data;
|
1012
|
-
if (message) response.message = message;
|
1013
|
-
if (error) response.error = error;
|
1014
|
-
if (meta) response.meta = meta;
|
1015
|
-
return response;
|
1016
|
-
}
|
1017
|
-
function sendSuccess(res, data, message, statusCode = 200, meta) {
|
1018
|
-
res.status(statusCode).json(apiResponse(true, data, message, void 0, meta));
|
728
|
+
return w.on("SIGTERM", () => f("SIGTERM")), w.on("SIGINT", () => f("SIGINT")), p;
|
729
|
+
}, t;
|
1019
730
|
}
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
function getPaginationParams(req) {
|
1025
|
-
const page = parseInt(req.query.page) || 1;
|
1026
|
-
const limit = parseInt(req.query.limit) || 10;
|
1027
|
-
const sort = req.query.sort || "createdAt";
|
1028
|
-
const order = req.query.order === "asc" ? "asc" : "desc";
|
1029
|
-
return { page, limit, sort, order };
|
1030
|
-
}
|
1031
|
-
function paginationMiddleware(req, res, next) {
|
1032
|
-
req.pagination = getPaginationParams(req);
|
1033
|
-
next();
|
1034
|
-
}
|
1035
|
-
function validateRequest(schema) {
|
1036
|
-
return (req, res, next) => {
|
1037
|
-
try {
|
1038
|
-
const { error, value } = schema.validate(req.body);
|
1039
|
-
if (error) {
|
1040
|
-
sendError(res, `Validation error: ${error.message}`, 400);
|
1041
|
-
return;
|
1042
|
-
}
|
1043
|
-
req.body = value;
|
1044
|
-
next();
|
1045
|
-
} catch (err) {
|
1046
|
-
sendError(res, "Validation error", 400);
|
1047
|
-
}
|
1048
|
-
};
|
1049
|
-
}
|
1050
|
-
function createApiRouter(options = {}, auth) {
|
1051
|
-
const router = Router();
|
1052
|
-
if (options.requireAuth && auth) {
|
1053
|
-
router.use(auth.authenticate);
|
1054
|
-
if (options.requiredRole) {
|
1055
|
-
router.use(auth.hasRole(options.requiredRole));
|
1056
|
-
}
|
1057
|
-
}
|
1058
|
-
if (options.rateLimit) {
|
1059
|
-
console.warn("Rate limiting is disabled: express-rate-limit dependency is not installed");
|
1060
|
-
}
|
1061
|
-
return router;
|
1062
|
-
}
|
1063
|
-
function asyncHandler(fn) {
|
1064
|
-
return (req, res, next) => {
|
1065
|
-
fn(req, res, next).catch(next);
|
1066
|
-
};
|
1067
|
-
}
|
1068
|
-
function createRestEndpoints(model) {
|
1069
|
-
const router = Router();
|
1070
|
-
router.get("/", paginationMiddleware, asyncHandler(async (req, res) => {
|
1071
|
-
const result = await model.getAll(req.pagination);
|
1072
|
-
sendSuccess(res, result);
|
1073
|
-
}));
|
1074
|
-
router.get("/:id", asyncHandler(async (req, res) => {
|
1075
|
-
const item = await model.getById(req.params.id);
|
1076
|
-
if (!item) {
|
1077
|
-
return sendError(res, "Item not found", 404);
|
1078
|
-
}
|
1079
|
-
sendSuccess(res, item);
|
1080
|
-
}));
|
1081
|
-
router.post("/", asyncHandler(async (req, res) => {
|
1082
|
-
const newItem = await model.create(req.body);
|
1083
|
-
sendSuccess(res, newItem, "Item created successfully", 201);
|
1084
|
-
}));
|
1085
|
-
router.put("/:id", asyncHandler(async (req, res) => {
|
1086
|
-
const updatedItem = await model.update(req.params.id, req.body);
|
1087
|
-
if (!updatedItem) {
|
1088
|
-
return sendError(res, "Item not found", 404);
|
1089
|
-
}
|
1090
|
-
sendSuccess(res, updatedItem, "Item updated successfully");
|
1091
|
-
}));
|
1092
|
-
router.delete("/:id", asyncHandler(async (req, res) => {
|
1093
|
-
const result = await model.delete(req.params.id);
|
1094
|
-
if (!result) {
|
1095
|
-
return sendError(res, "Item not found", 404);
|
1096
|
-
}
|
1097
|
-
sendSuccess(res, null, "Item deleted successfully");
|
1098
|
-
}));
|
1099
|
-
return router;
|
1100
|
-
}
|
1101
|
-
const crypto = {};
|
1102
|
-
class Auth {
|
1103
|
-
constructor(options) {
|
1104
|
-
this.loginAttempts = /* @__PURE__ */ new Map();
|
1105
|
-
this.login = async (req, res) => {
|
731
|
+
const me = fe.default || fe;
|
732
|
+
class et {
|
733
|
+
constructor(t) {
|
734
|
+
if (this.loginAttempts = /* @__PURE__ */ new Map(), this.login = async (e, s) => {
|
1106
735
|
try {
|
1107
|
-
const { username, password } =
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
success: false,
|
736
|
+
const { username: n, password: i } = e.body, o = e.ip || e.connection.remoteAddress || "";
|
737
|
+
if (!this.checkRateLimit(o)) {
|
738
|
+
s.status(429).json({
|
739
|
+
success: !1,
|
1112
740
|
message: "Too many login attempts. Please try again later."
|
1113
741
|
});
|
1114
742
|
return;
|
1115
743
|
}
|
1116
|
-
if (!
|
1117
|
-
|
1118
|
-
success:
|
744
|
+
if (!n || !i) {
|
745
|
+
s.status(400).json({
|
746
|
+
success: !1,
|
1119
747
|
message: "Username and password are required"
|
1120
748
|
});
|
1121
749
|
return;
|
1122
750
|
}
|
1123
751
|
if (!this.options.findUser) {
|
1124
|
-
|
1125
|
-
success:
|
752
|
+
s.status(500).json({
|
753
|
+
success: !1,
|
1126
754
|
message: "User finder function not configured"
|
1127
755
|
});
|
1128
756
|
return;
|
1129
757
|
}
|
1130
|
-
const
|
1131
|
-
if (!
|
1132
|
-
|
1133
|
-
success:
|
758
|
+
const a = await this.options.findUser(n);
|
759
|
+
if (!a) {
|
760
|
+
s.status(401).json({
|
761
|
+
success: !1,
|
1134
762
|
message: "Invalid credentials"
|
1135
763
|
});
|
1136
764
|
return;
|
1137
765
|
}
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
)
|
1142
|
-
|
1143
|
-
|
1144
|
-
success: false,
|
766
|
+
if (!await this.options.verifyPassword(
|
767
|
+
i,
|
768
|
+
a.password
|
769
|
+
)) {
|
770
|
+
s.status(401).json({
|
771
|
+
success: !1,
|
1145
772
|
message: "Invalid credentials"
|
1146
773
|
});
|
1147
774
|
return;
|
1148
775
|
}
|
1149
|
-
const
|
1150
|
-
delete
|
1151
|
-
const
|
1152
|
-
id:
|
1153
|
-
username:
|
1154
|
-
role:
|
776
|
+
const d = { ...a };
|
777
|
+
delete d.password;
|
778
|
+
const h = this.generateTokenPair({
|
779
|
+
id: a.id || a._id,
|
780
|
+
username: a.username,
|
781
|
+
role: a.role || "user"
|
1155
782
|
});
|
1156
783
|
if (this.options.saveRefreshToken) {
|
1157
|
-
const
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
refreshExpiry
|
784
|
+
const E = /* @__PURE__ */ new Date();
|
785
|
+
E.setSeconds(E.getSeconds() + this.getExpirationSeconds(this.options.refreshExpiration || "7d")), await this.options.saveRefreshToken(
|
786
|
+
a.id || a._id,
|
787
|
+
h.refreshToken,
|
788
|
+
E
|
1163
789
|
);
|
1164
790
|
}
|
1165
|
-
|
1166
|
-
|
1167
|
-
}
|
1168
|
-
res.json({
|
1169
|
-
success: true,
|
791
|
+
e.body.useCookies && this.setAuthCookies(s, h), s.json({
|
792
|
+
success: !0,
|
1170
793
|
message: "Authentication successful",
|
1171
|
-
tokens:
|
1172
|
-
user:
|
794
|
+
tokens: h,
|
795
|
+
user: d
|
1173
796
|
});
|
1174
|
-
} catch (
|
1175
|
-
console.error("Authentication error:",
|
1176
|
-
|
1177
|
-
success: false,
|
797
|
+
} catch (n) {
|
798
|
+
console.error("Authentication error:", n), s.status(500).json({
|
799
|
+
success: !1,
|
1178
800
|
message: "Authentication failed",
|
1179
|
-
error:
|
801
|
+
error: w.env.NODE_ENV !== "production" ? n.message : void 0
|
1180
802
|
});
|
1181
803
|
}
|
1182
|
-
}
|
1183
|
-
|
1184
|
-
var _a, _b;
|
804
|
+
}, this.refreshToken = async (e, s) => {
|
805
|
+
var n, i;
|
1185
806
|
try {
|
1186
|
-
const
|
1187
|
-
if (!
|
1188
|
-
|
1189
|
-
success:
|
807
|
+
const o = ((n = e.cookies) == null ? void 0 : n.refreshToken) || e.body.refreshToken;
|
808
|
+
if (!o) {
|
809
|
+
s.status(401).json({
|
810
|
+
success: !1,
|
1190
811
|
message: "Refresh token required"
|
1191
812
|
});
|
1192
813
|
return;
|
1193
814
|
}
|
1194
|
-
const
|
1195
|
-
if (this.options.verifyRefreshToken) {
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
message: "Invalid refresh token"
|
1202
|
-
});
|
1203
|
-
return;
|
1204
|
-
}
|
815
|
+
const a = this.verifyToken(o, "refresh");
|
816
|
+
if (this.options.verifyRefreshToken && !await this.options.verifyRefreshToken(a.id, o)) {
|
817
|
+
this.clearAuthCookies(s), s.status(401).json({
|
818
|
+
success: !1,
|
819
|
+
message: "Invalid refresh token"
|
820
|
+
});
|
821
|
+
return;
|
1205
822
|
}
|
1206
|
-
const
|
1207
|
-
id:
|
823
|
+
const c = this.generateTokenPair({
|
824
|
+
id: a.id,
|
1208
825
|
// We need to fetch the user data again for complete payload
|
1209
|
-
...this.options.findUser ? await this.options.findUser(
|
826
|
+
...this.options.findUser ? await this.options.findUser(a.id) : {}
|
1210
827
|
});
|
1211
828
|
if (this.options.saveRefreshToken) {
|
1212
|
-
const
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
refreshExpiry
|
829
|
+
const h = /* @__PURE__ */ new Date();
|
830
|
+
h.setSeconds(h.getSeconds() + this.getExpirationSeconds(this.options.refreshExpiration || "7d")), await this.options.saveRefreshToken(
|
831
|
+
a.id,
|
832
|
+
c.refreshToken,
|
833
|
+
h
|
1218
834
|
);
|
1219
835
|
}
|
1220
|
-
|
1221
|
-
|
1222
|
-
this.setAuthCookies(res, tokenPair);
|
1223
|
-
}
|
1224
|
-
res.json({
|
1225
|
-
success: true,
|
836
|
+
(((i = e.cookies) == null ? void 0 : i.accessToken) || e.body.useCookies) && this.setAuthCookies(s, c), s.json({
|
837
|
+
success: !0,
|
1226
838
|
message: "Token refreshed successfully",
|
1227
|
-
tokens:
|
839
|
+
tokens: c
|
1228
840
|
});
|
1229
|
-
} catch (
|
1230
|
-
this.clearAuthCookies(
|
1231
|
-
|
1232
|
-
success: false,
|
841
|
+
} catch (o) {
|
842
|
+
this.clearAuthCookies(s), s.status(401).json({
|
843
|
+
success: !1,
|
1233
844
|
message: "Invalid or expired refresh token",
|
1234
|
-
error:
|
845
|
+
error: w.env.NODE_ENV !== "production" ? o.message : void 0
|
1235
846
|
});
|
1236
847
|
}
|
1237
|
-
}
|
1238
|
-
|
1239
|
-
var _a;
|
848
|
+
}, this.logout = async (e, s) => {
|
849
|
+
var n;
|
1240
850
|
try {
|
1241
|
-
this.clearAuthCookies(
|
1242
|
-
const
|
1243
|
-
if (
|
851
|
+
this.clearAuthCookies(s);
|
852
|
+
const i = ((n = e.cookies) == null ? void 0 : n.refreshToken) || e.body.refreshToken;
|
853
|
+
if (i && this.options.saveRefreshToken)
|
1244
854
|
try {
|
1245
|
-
const
|
1246
|
-
|
1247
|
-
|
1248
|
-
}
|
1249
|
-
} catch (e) {
|
855
|
+
const o = this.verifyToken(i, "refresh");
|
856
|
+
typeof this.options.saveRefreshToken == "function" && await this.options.saveRefreshToken(o.id, "", /* @__PURE__ */ new Date());
|
857
|
+
} catch {
|
1250
858
|
}
|
1251
|
-
}
|
1252
|
-
|
1253
|
-
|
1254
|
-
console.error("Logout error:", error);
|
1255
|
-
res.status(500).json({ success: false, message: "Logout failed", error: error.message });
|
859
|
+
s.json({ success: !0, message: "Logged out successfully" });
|
860
|
+
} catch (i) {
|
861
|
+
console.error("Logout error:", i), s.status(500).json({ success: !1, message: "Logout failed", error: i.message });
|
1256
862
|
}
|
1257
|
-
}
|
1258
|
-
|
1259
|
-
var _a;
|
863
|
+
}, this.authenticate = (e, s, n) => {
|
864
|
+
var i;
|
1260
865
|
try {
|
1261
|
-
let
|
1262
|
-
if (!
|
1263
|
-
const
|
1264
|
-
|
1265
|
-
token = authHeader.split(" ")[1];
|
1266
|
-
}
|
866
|
+
let o = (i = e.cookies) == null ? void 0 : i.accessToken;
|
867
|
+
if (!o) {
|
868
|
+
const c = e.headers.authorization;
|
869
|
+
c && c.startsWith("Bearer ") && (o = c.split(" ")[1]);
|
1267
870
|
}
|
1268
|
-
if (!
|
1269
|
-
|
1270
|
-
success:
|
871
|
+
if (!o) {
|
872
|
+
s.status(401).json({
|
873
|
+
success: !1,
|
1271
874
|
message: "Authentication required"
|
1272
875
|
});
|
1273
876
|
return;
|
1274
877
|
}
|
1275
|
-
const
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
success: false,
|
878
|
+
const a = this.verifyToken(o, "access");
|
879
|
+
e.user = a, n();
|
880
|
+
} catch (o) {
|
881
|
+
s.status(401).json({
|
882
|
+
success: !1,
|
1281
883
|
message: "Invalid or expired token",
|
1282
|
-
error:
|
884
|
+
error: w.env.NODE_ENV !== "production" ? o.message : void 0
|
1283
885
|
});
|
1284
886
|
}
|
1285
|
-
}
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
} else {
|
1300
|
-
res.status(403).json({
|
1301
|
-
success: false,
|
1302
|
-
message: "Insufficient permissions"
|
1303
|
-
});
|
1304
|
-
}
|
1305
|
-
};
|
1306
|
-
};
|
1307
|
-
this.options = {
|
887
|
+
}, this.hasRole = (e) => (s, n, i) => {
|
888
|
+
const o = s.user;
|
889
|
+
if (!o) {
|
890
|
+
n.status(401).json({
|
891
|
+
success: !1,
|
892
|
+
message: "Authentication required"
|
893
|
+
});
|
894
|
+
return;
|
895
|
+
}
|
896
|
+
(Array.isArray(e) ? e : [e]).includes(o.role) ? i() : n.status(403).json({
|
897
|
+
success: !1,
|
898
|
+
message: "Insufficient permissions"
|
899
|
+
});
|
900
|
+
}, this.options = {
|
1308
901
|
tokenExpiration: "15m",
|
1309
902
|
refreshExpiration: "7d",
|
1310
903
|
saltRounds: 10,
|
1311
|
-
secureCookies:
|
1312
|
-
httpOnlyCookies:
|
1313
|
-
rateLimit:
|
1314
|
-
...
|
1315
|
-
refreshSecret:
|
1316
|
-
}
|
1317
|
-
if (!options.jwtSecret) {
|
904
|
+
secureCookies: w.env.NODE_ENV === "production",
|
905
|
+
httpOnlyCookies: !0,
|
906
|
+
rateLimit: !0,
|
907
|
+
...t,
|
908
|
+
refreshSecret: t.refreshSecret || t.jwtSecret
|
909
|
+
}, !t.jwtSecret)
|
1318
910
|
throw new Error("JWT secret is required for authentication");
|
1319
|
-
|
1320
|
-
if (!this.options.verifyPassword) {
|
1321
|
-
this.options.verifyPassword = this.verifyPasswordWithBcrypt;
|
1322
|
-
}
|
911
|
+
this.options.verifyPassword || (this.options.verifyPassword = this.verifyPasswordWithBcrypt);
|
1323
912
|
}
|
1324
913
|
/**
|
1325
914
|
* Hash a password using bcrypt
|
1326
915
|
*/
|
1327
|
-
async hashPassword(
|
1328
|
-
return await
|
916
|
+
async hashPassword(t) {
|
917
|
+
return await me.hash(t, this.options.saltRounds || 10);
|
1329
918
|
}
|
1330
919
|
/**
|
1331
920
|
* Verify a password against a hash using bcrypt
|
1332
921
|
*/
|
1333
|
-
async verifyPasswordWithBcrypt(
|
1334
|
-
return await
|
922
|
+
async verifyPasswordWithBcrypt(t, e) {
|
923
|
+
return await me.compare(t, e);
|
1335
924
|
}
|
1336
925
|
/**
|
1337
926
|
* Generate a cryptographically secure random token
|
1338
927
|
*/
|
1339
|
-
generateSecureToken(
|
1340
|
-
return
|
928
|
+
generateSecureToken(t = 32) {
|
929
|
+
return Me.randomBytes(t).toString("hex");
|
1341
930
|
}
|
1342
931
|
/**
|
1343
932
|
* Generate token pair (access token + refresh token)
|
1344
933
|
*/
|
1345
|
-
generateTokenPair(
|
1346
|
-
const
|
1347
|
-
|
1348
|
-
{ ...payload, type: "access" },
|
934
|
+
generateTokenPair(t) {
|
935
|
+
const e = this.getExpirationSeconds(this.options.tokenExpiration || "15m"), s = z.sign(
|
936
|
+
{ ...t, type: "access" },
|
1349
937
|
this.options.jwtSecret,
|
1350
938
|
{ expiresIn: this.options.tokenExpiration }
|
1351
|
-
)
|
1352
|
-
|
1353
|
-
{ id: payload.id, type: "refresh" },
|
939
|
+
), n = z.sign(
|
940
|
+
{ id: t.id, type: "refresh" },
|
1354
941
|
this.options.refreshSecret,
|
1355
942
|
{ expiresIn: this.options.refreshExpiration }
|
1356
943
|
);
|
1357
944
|
return {
|
1358
|
-
accessToken,
|
1359
|
-
refreshToken,
|
1360
|
-
expiresIn
|
945
|
+
accessToken: s,
|
946
|
+
refreshToken: n,
|
947
|
+
expiresIn: e
|
1361
948
|
};
|
1362
949
|
}
|
1363
950
|
/**
|
1364
951
|
* Convert JWT expiration time to seconds
|
1365
952
|
*/
|
1366
|
-
getExpirationSeconds(
|
1367
|
-
const
|
1368
|
-
|
1369
|
-
switch (unit) {
|
953
|
+
getExpirationSeconds(t) {
|
954
|
+
const e = t.charAt(t.length - 1), s = parseInt(t.slice(0, -1));
|
955
|
+
switch (e) {
|
1370
956
|
case "s":
|
1371
|
-
return
|
957
|
+
return s;
|
1372
958
|
case "m":
|
1373
|
-
return
|
959
|
+
return s * 60;
|
1374
960
|
case "h":
|
1375
|
-
return
|
961
|
+
return s * 60 * 60;
|
1376
962
|
case "d":
|
1377
|
-
return
|
963
|
+
return s * 60 * 60 * 24;
|
1378
964
|
default:
|
1379
965
|
return 3600;
|
1380
966
|
}
|
@@ -1382,37 +968,35 @@ class Auth {
|
|
1382
968
|
/**
|
1383
969
|
* Verify a JWT token
|
1384
970
|
*/
|
1385
|
-
verifyToken(
|
971
|
+
verifyToken(t, e = "access") {
|
1386
972
|
try {
|
1387
|
-
const
|
1388
|
-
|
1389
|
-
if (typeof decoded === "object" && decoded.type !== type) {
|
973
|
+
const s = e === "access" ? this.options.jwtSecret : this.options.refreshSecret, n = z.verify(t, s);
|
974
|
+
if (typeof n == "object" && n.type !== e)
|
1390
975
|
throw new Error("Invalid token type");
|
1391
|
-
|
1392
|
-
|
1393
|
-
} catch (error) {
|
976
|
+
return n;
|
977
|
+
} catch {
|
1394
978
|
throw new Error("Invalid or expired token");
|
1395
979
|
}
|
1396
980
|
}
|
1397
981
|
/**
|
1398
982
|
* Set authentication cookies
|
1399
983
|
*/
|
1400
|
-
setAuthCookies(
|
1401
|
-
|
984
|
+
setAuthCookies(t, e) {
|
985
|
+
t.cookie("accessToken", e.accessToken, {
|
1402
986
|
httpOnly: this.options.httpOnlyCookies,
|
1403
987
|
secure: this.options.secureCookies,
|
1404
988
|
domain: this.options.cookieDomain,
|
1405
989
|
sameSite: "strict",
|
1406
|
-
maxAge:
|
990
|
+
maxAge: e.expiresIn * 1e3
|
1407
991
|
});
|
1408
|
-
const
|
1409
|
-
|
1410
|
-
httpOnly:
|
992
|
+
const s = this.getExpirationSeconds(this.options.refreshExpiration || "7d");
|
993
|
+
t.cookie("refreshToken", e.refreshToken, {
|
994
|
+
httpOnly: !0,
|
1411
995
|
// Always HTTP only for refresh tokens
|
1412
996
|
secure: this.options.secureCookies,
|
1413
997
|
domain: this.options.cookieDomain,
|
1414
998
|
sameSite: "strict",
|
1415
|
-
maxAge:
|
999
|
+
maxAge: s * 1e3,
|
1416
1000
|
path: "/api/auth/refresh"
|
1417
1001
|
// Restrict to refresh endpoint
|
1418
1002
|
});
|
@@ -1420,169 +1004,123 @@ class Auth {
|
|
1420
1004
|
/**
|
1421
1005
|
* Clear authentication cookies
|
1422
1006
|
*/
|
1423
|
-
clearAuthCookies(
|
1424
|
-
|
1425
|
-
res.clearCookie("refreshToken", { path: "/api/auth/refresh" });
|
1007
|
+
clearAuthCookies(t) {
|
1008
|
+
t.clearCookie("accessToken"), t.clearCookie("refreshToken", { path: "/api/auth/refresh" });
|
1426
1009
|
}
|
1427
1010
|
/**
|
1428
1011
|
* Check and handle rate limiting
|
1429
1012
|
*/
|
1430
|
-
checkRateLimit(
|
1431
|
-
if (!this.options.rateLimit)
|
1432
|
-
return
|
1433
|
-
|
1434
|
-
|
1435
|
-
const attempt = this.loginAttempts.get(ip);
|
1436
|
-
if (!attempt) {
|
1437
|
-
this.loginAttempts.set(ip, { count: 1, resetTime: now + 36e5 });
|
1438
|
-
return true;
|
1439
|
-
}
|
1440
|
-
if (now > attempt.resetTime) {
|
1441
|
-
this.loginAttempts.set(ip, { count: 1, resetTime: now + 36e5 });
|
1442
|
-
return true;
|
1443
|
-
}
|
1444
|
-
if (attempt.count >= 5) {
|
1445
|
-
return false;
|
1446
|
-
}
|
1447
|
-
attempt.count++;
|
1448
|
-
this.loginAttempts.set(ip, attempt);
|
1449
|
-
return true;
|
1013
|
+
checkRateLimit(t) {
|
1014
|
+
if (!this.options.rateLimit)
|
1015
|
+
return !0;
|
1016
|
+
const e = Date.now(), s = this.loginAttempts.get(t);
|
1017
|
+
return s ? e > s.resetTime ? (this.loginAttempts.set(t, { count: 1, resetTime: e + 36e5 }), !0) : s.count >= 5 ? !1 : (s.count++, this.loginAttempts.set(t, s), !0) : (this.loginAttempts.set(t, { count: 1, resetTime: e + 36e5 }), !0);
|
1450
1018
|
}
|
1451
1019
|
}
|
1452
|
-
function
|
1453
|
-
return new
|
1020
|
+
function tt(r) {
|
1021
|
+
return new et(r);
|
1454
1022
|
}
|
1455
|
-
function
|
1456
|
-
const
|
1023
|
+
function rt(r, t) {
|
1024
|
+
const e = $.model(r, t);
|
1457
1025
|
return {
|
1458
|
-
getAll: async (
|
1026
|
+
getAll: async (s) => {
|
1459
1027
|
try {
|
1460
|
-
const { page = 1, limit = 10, sort = "_id", order = "desc" } =
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
const [results, total] = await Promise.all([
|
1465
|
-
mongooseModel.find().sort(sortOptions).skip(skip).limit(limit).exec(),
|
1466
|
-
mongooseModel.countDocuments().exec()
|
1467
|
-
]);
|
1468
|
-
const totalPages = Math.ceil(total / limit);
|
1028
|
+
const { page: n = 1, limit: i = 10, sort: o = "_id", order: a = "desc" } = s || {}, c = (n - 1) * i, d = a === "asc" ? 1 : -1, h = { [o]: d }, [E, S] = await Promise.all([
|
1029
|
+
e.find().sort(h).skip(c).limit(i).exec(),
|
1030
|
+
e.countDocuments().exec()
|
1031
|
+
]), y = Math.ceil(S / i);
|
1469
1032
|
return {
|
1470
|
-
data:
|
1033
|
+
data: E,
|
1471
1034
|
pagination: {
|
1472
|
-
total,
|
1473
|
-
totalPages,
|
1474
|
-
currentPage:
|
1475
|
-
limit,
|
1476
|
-
hasNextPage:
|
1477
|
-
hasPrevPage:
|
1035
|
+
total: S,
|
1036
|
+
totalPages: y,
|
1037
|
+
currentPage: n,
|
1038
|
+
limit: i,
|
1039
|
+
hasNextPage: n < y,
|
1040
|
+
hasPrevPage: n > 1
|
1478
1041
|
}
|
1479
1042
|
};
|
1480
|
-
} catch (
|
1481
|
-
console.error(`Error in ${
|
1482
|
-
throw new Error(`Failed to retrieve ${name} records: ${error.message}`);
|
1043
|
+
} catch (n) {
|
1044
|
+
throw console.error(`Error in ${r}.getAll:`, n), new Error(`Failed to retrieve ${r} records: ${n.message}`);
|
1483
1045
|
}
|
1484
1046
|
},
|
1485
|
-
getById: async (
|
1047
|
+
getById: async (s) => {
|
1486
1048
|
try {
|
1487
|
-
|
1488
|
-
|
1489
|
-
}
|
1490
|
-
return await mongooseModel.findById(id).exec();
|
1491
|
-
} catch (error) {
|
1492
|
-
console.error(`Error in ${name}.getById:`, error);
|
1493
|
-
throw new Error(`Failed to retrieve ${name} by ID: ${error.message}`);
|
1049
|
+
return $.isValidObjectId(s) ? await e.findById(s).exec() : null;
|
1050
|
+
} catch (n) {
|
1051
|
+
throw console.error(`Error in ${r}.getById:`, n), new Error(`Failed to retrieve ${r} by ID: ${n.message}`);
|
1494
1052
|
}
|
1495
1053
|
},
|
1496
|
-
create: async (
|
1054
|
+
create: async (s) => {
|
1497
1055
|
try {
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
console.error(`Error in ${name}.create:`, error);
|
1502
|
-
throw new Error(`Failed to create ${name}: ${error.message}`);
|
1056
|
+
return await new e(s).save();
|
1057
|
+
} catch (n) {
|
1058
|
+
throw console.error(`Error in ${r}.create:`, n), new Error(`Failed to create ${r}: ${n.message}`);
|
1503
1059
|
}
|
1504
1060
|
},
|
1505
|
-
createMany: async (
|
1061
|
+
createMany: async (s) => {
|
1506
1062
|
try {
|
1507
|
-
return await
|
1508
|
-
} catch (
|
1509
|
-
console.error(`Error in ${
|
1510
|
-
throw new Error(`Failed to create multiple ${name} records: ${error.message}`);
|
1063
|
+
return await e.insertMany(s);
|
1064
|
+
} catch (n) {
|
1065
|
+
throw console.error(`Error in ${r}.createMany:`, n), new Error(`Failed to create multiple ${r} records: ${n.message}`);
|
1511
1066
|
}
|
1512
1067
|
},
|
1513
|
-
update: async (
|
1068
|
+
update: async (s, n) => {
|
1514
1069
|
try {
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
).exec();
|
1523
|
-
} catch (error) {
|
1524
|
-
console.error(`Error in ${name}.update:`, error);
|
1525
|
-
throw new Error(`Failed to update ${name}: ${error.message}`);
|
1070
|
+
return $.isValidObjectId(s) ? await e.findByIdAndUpdate(
|
1071
|
+
s,
|
1072
|
+
{ $set: n },
|
1073
|
+
{ new: !0, runValidators: !0 }
|
1074
|
+
).exec() : null;
|
1075
|
+
} catch (i) {
|
1076
|
+
throw console.error(`Error in ${r}.update:`, i), new Error(`Failed to update ${r}: ${i.message}`);
|
1526
1077
|
}
|
1527
1078
|
},
|
1528
|
-
delete: async (
|
1079
|
+
delete: async (s) => {
|
1529
1080
|
try {
|
1530
|
-
|
1531
|
-
|
1532
|
-
}
|
1533
|
-
const result = await mongooseModel.findByIdAndDelete(id).exec();
|
1534
|
-
return result !== null;
|
1535
|
-
} catch (error) {
|
1536
|
-
console.error(`Error in ${name}.delete:`, error);
|
1537
|
-
throw new Error(`Failed to delete ${name}: ${error.message}`);
|
1081
|
+
return $.isValidObjectId(s) ? await e.findByIdAndDelete(s).exec() !== null : !1;
|
1082
|
+
} catch (n) {
|
1083
|
+
throw console.error(`Error in ${r}.delete:`, n), new Error(`Failed to delete ${r}: ${n.message}`);
|
1538
1084
|
}
|
1539
1085
|
},
|
1540
|
-
find: async (
|
1086
|
+
find: async (s, n) => {
|
1541
1087
|
try {
|
1542
|
-
const { page = 1, limit = 10, sort = "_id", order = "desc" } =
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
const [results, total] = await Promise.all([
|
1547
|
-
mongooseModel.find(query).sort(sortOptions).skip(skip).limit(limit).exec(),
|
1548
|
-
mongooseModel.countDocuments(query).exec()
|
1549
|
-
]);
|
1550
|
-
const totalPages = Math.ceil(total / limit);
|
1088
|
+
const { page: i = 1, limit: o = 10, sort: a = "_id", order: c = "desc" } = n || {}, d = (i - 1) * o, h = c === "asc" ? 1 : -1, E = { [a]: h }, [S, y] = await Promise.all([
|
1089
|
+
e.find(s).sort(E).skip(d).limit(o).exec(),
|
1090
|
+
e.countDocuments(s).exec()
|
1091
|
+
]), I = Math.ceil(y / o);
|
1551
1092
|
return {
|
1552
|
-
data:
|
1093
|
+
data: S,
|
1553
1094
|
pagination: {
|
1554
|
-
total,
|
1555
|
-
totalPages,
|
1556
|
-
currentPage:
|
1557
|
-
limit,
|
1558
|
-
hasNextPage:
|
1559
|
-
hasPrevPage:
|
1095
|
+
total: y,
|
1096
|
+
totalPages: I,
|
1097
|
+
currentPage: i,
|
1098
|
+
limit: o,
|
1099
|
+
hasNextPage: i < I,
|
1100
|
+
hasPrevPage: i > 1
|
1560
1101
|
}
|
1561
1102
|
};
|
1562
|
-
} catch (
|
1563
|
-
console.error(`Error in ${
|
1564
|
-
throw new Error(`Failed to find ${name} records: ${error.message}`);
|
1103
|
+
} catch (i) {
|
1104
|
+
throw console.error(`Error in ${r}.find:`, i), new Error(`Failed to find ${r} records: ${i.message}`);
|
1565
1105
|
}
|
1566
1106
|
},
|
1567
|
-
count: async (
|
1107
|
+
count: async (s) => {
|
1568
1108
|
try {
|
1569
|
-
return await
|
1570
|
-
} catch (
|
1571
|
-
console.error(`Error in ${
|
1572
|
-
throw new Error(`Failed to count ${name} records: ${error.message}`);
|
1109
|
+
return await e.countDocuments(s || {}).exec();
|
1110
|
+
} catch (n) {
|
1111
|
+
throw console.error(`Error in ${r}.count:`, n), new Error(`Failed to count ${r} records: ${n.message}`);
|
1573
1112
|
}
|
1574
1113
|
},
|
1575
|
-
findOne: async (
|
1114
|
+
findOne: async (s) => {
|
1576
1115
|
try {
|
1577
|
-
return await
|
1578
|
-
} catch (
|
1579
|
-
console.error(`Error in ${
|
1580
|
-
throw new Error(`Failed to find ${name} record: ${error.message}`);
|
1116
|
+
return await e.findOne(s).exec();
|
1117
|
+
} catch (n) {
|
1118
|
+
throw console.error(`Error in ${r}.findOne:`, n), new Error(`Failed to find ${r} record: ${n.message}`);
|
1581
1119
|
}
|
1582
1120
|
}
|
1583
1121
|
};
|
1584
1122
|
}
|
1585
|
-
const
|
1123
|
+
const st = {
|
1586
1124
|
String: { type: String },
|
1587
1125
|
Number: { type: Number },
|
1588
1126
|
Boolean: { type: Boolean },
|
@@ -1590,75 +1128,250 @@ const FieldTypes = {
|
|
1590
1128
|
ObjectId: { type: String },
|
1591
1129
|
// Fallback to String instead of using Schema.Types.ObjectId
|
1592
1130
|
// Helper functions for common field patterns
|
1593
|
-
Required: (
|
1594
|
-
Unique: (
|
1595
|
-
Ref: (
|
1131
|
+
Required: (r) => ({ ...r, required: !0 }),
|
1132
|
+
Unique: (r) => ({ ...r, unique: !0 }),
|
1133
|
+
Ref: (r) => ({
|
1596
1134
|
type: String,
|
1597
1135
|
// Fallback to String type for tests
|
1598
|
-
ref:
|
1136
|
+
ref: r
|
1599
1137
|
}),
|
1600
|
-
Enum: (
|
1601
|
-
Default: (
|
1138
|
+
Enum: (r) => ({ type: String, enum: r }),
|
1139
|
+
Default: (r, t) => ({ ...r, default: t }),
|
1602
1140
|
// Array field type
|
1603
|
-
Array: (
|
1141
|
+
Array: (r) => ({ type: [r] })
|
1142
|
+
}, Ce = (r, { res: t }) => {
|
1143
|
+
console.error("API Error:", r);
|
1144
|
+
const e = r.status || r.statusCode || 500, s = r.message || "Internal server error";
|
1145
|
+
t.status(e).json({
|
1146
|
+
success: !1,
|
1147
|
+
error: s,
|
1148
|
+
stack: w.env.NODE_ENV !== "production" ? r.stack : void 0
|
1149
|
+
});
|
1604
1150
|
};
|
1605
|
-
|
1151
|
+
function nt(r, t = {}) {
|
1152
|
+
const e = O.Router(), { middleware: s = [], errorHandler: n = Ce } = t;
|
1153
|
+
s.forEach((o) => e.use(o));
|
1154
|
+
const i = (o) => async (a, c, d) => {
|
1155
|
+
try {
|
1156
|
+
const h = { req: a, res: c, next: d, params: a.params, query: a.query, body: a.body };
|
1157
|
+
return await o(h);
|
1158
|
+
} catch (h) {
|
1159
|
+
const E = { req: a, res: c, next: d, params: a.params, query: a.query, body: a.body };
|
1160
|
+
return n(h, E);
|
1161
|
+
}
|
1162
|
+
};
|
1163
|
+
return e.get("/", i(async ({ req: o, res: a }) => {
|
1164
|
+
const c = o.pagination || { page: 1, limit: 10 }, d = await r.getAll(c);
|
1165
|
+
a.json({
|
1166
|
+
success: !0,
|
1167
|
+
...d
|
1168
|
+
});
|
1169
|
+
})), e.get("/:id", i(async ({ params: o, res: a }) => {
|
1170
|
+
const c = await r.getById(o.id);
|
1171
|
+
if (!c) {
|
1172
|
+
a.status(404).json({
|
1173
|
+
success: !1,
|
1174
|
+
error: "Item not found"
|
1175
|
+
});
|
1176
|
+
return;
|
1177
|
+
}
|
1178
|
+
a.json({
|
1179
|
+
success: !0,
|
1180
|
+
data: c
|
1181
|
+
});
|
1182
|
+
})), e.post("/", i(async ({ body: o, res: a }) => {
|
1183
|
+
const c = await r.create(o);
|
1184
|
+
a.status(201).json({
|
1185
|
+
success: !0,
|
1186
|
+
data: c,
|
1187
|
+
message: "Item created successfully"
|
1188
|
+
});
|
1189
|
+
})), e.put("/:id", i(async ({ params: o, body: a, res: c }) => {
|
1190
|
+
const d = await r.update(o.id, a);
|
1191
|
+
if (!d) {
|
1192
|
+
c.status(404).json({
|
1193
|
+
success: !1,
|
1194
|
+
error: "Item not found"
|
1195
|
+
});
|
1196
|
+
return;
|
1197
|
+
}
|
1198
|
+
c.json({
|
1199
|
+
success: !0,
|
1200
|
+
data: d,
|
1201
|
+
message: "Item updated successfully"
|
1202
|
+
});
|
1203
|
+
})), e.delete("/:id", i(async ({ params: o, res: a }) => {
|
1204
|
+
if (!await r.delete(o.id)) {
|
1205
|
+
a.status(404).json({
|
1206
|
+
success: !1,
|
1207
|
+
error: "Item not found"
|
1208
|
+
});
|
1209
|
+
return;
|
1210
|
+
}
|
1211
|
+
a.json({
|
1212
|
+
success: !0,
|
1213
|
+
message: "Item deleted successfully"
|
1214
|
+
});
|
1215
|
+
})), e;
|
1216
|
+
}
|
1217
|
+
function ot(r, t = {}) {
|
1218
|
+
const e = O.Router(), { middleware: s = [], errorHandler: n = Ce } = t;
|
1219
|
+
s.forEach((o) => e.use(o));
|
1220
|
+
const i = (o) => async (a, c, d) => {
|
1221
|
+
try {
|
1222
|
+
const h = { req: a, res: c, next: d, params: a.params, query: a.query, body: a.body };
|
1223
|
+
return c.headersSent ? void 0 : await o(h);
|
1224
|
+
} catch (h) {
|
1225
|
+
if (c.headersSent) {
|
1226
|
+
console.error("Error occurred after response was sent:", h);
|
1227
|
+
return;
|
1228
|
+
}
|
1229
|
+
const E = { req: a, res: c, next: d, params: a.params, query: a.query, body: a.body };
|
1230
|
+
return n(h, E);
|
1231
|
+
}
|
1232
|
+
};
|
1233
|
+
return Object.entries(r).forEach(([o, a]) => {
|
1234
|
+
const { method: c, handler: d } = a;
|
1235
|
+
e[c](o, i(d));
|
1236
|
+
}), e;
|
1237
|
+
}
|
1238
|
+
function le(r, t, e, s, n) {
|
1239
|
+
const i = { success: r };
|
1240
|
+
return t !== void 0 && (i.data = t), e && (i.message = e), s && (i.error = s), n && (i.meta = n), i;
|
1241
|
+
}
|
1242
|
+
function R(r, t, e, s = 200, n) {
|
1243
|
+
r.status(s).json(le(!0, t, e, void 0, n));
|
1244
|
+
}
|
1245
|
+
function M(r, t, e = 400, s) {
|
1246
|
+
const n = t instanceof Error ? t.message : t;
|
1247
|
+
r.status(e).json(le(!1, void 0, void 0, n, s));
|
1248
|
+
}
|
1249
|
+
function $e(r) {
|
1250
|
+
const t = parseInt(r.query.page) || 1, e = parseInt(r.query.limit) || 10, s = r.query.sort || "createdAt", n = r.query.order === "asc" ? "asc" : "desc";
|
1251
|
+
return { page: t, limit: e, sort: s, order: n };
|
1252
|
+
}
|
1253
|
+
function je(r, t, e) {
|
1254
|
+
r.pagination = $e(r), e();
|
1255
|
+
}
|
1256
|
+
function it(r) {
|
1257
|
+
return (t, e, s) => {
|
1258
|
+
try {
|
1259
|
+
const { error: n, value: i } = r.validate(t.body);
|
1260
|
+
if (n) {
|
1261
|
+
M(e, `Validation error: ${n.message}`, 400);
|
1262
|
+
return;
|
1263
|
+
}
|
1264
|
+
t.body = i, s();
|
1265
|
+
} catch {
|
1266
|
+
M(e, "Validation error", 400);
|
1267
|
+
}
|
1268
|
+
};
|
1269
|
+
}
|
1270
|
+
function at(r = {}, t) {
|
1271
|
+
const e = ye();
|
1272
|
+
return r.requireAuth && t && (e.use(t.authenticate), r.requiredRole && e.use(t.hasRole(r.requiredRole))), r.rateLimit && console.warn("Rate limiting is disabled: express-rate-limit dependency is not installed"), e;
|
1273
|
+
}
|
1274
|
+
function N(r) {
|
1275
|
+
return (t, e, s) => {
|
1276
|
+
r(t, e, s).catch(s);
|
1277
|
+
};
|
1278
|
+
}
|
1279
|
+
function ct(r) {
|
1280
|
+
const t = ye();
|
1281
|
+
return t.get("/", je, N(async (e, s) => {
|
1282
|
+
const n = await r.getAll(e.pagination);
|
1283
|
+
R(s, n);
|
1284
|
+
})), t.get("/:id", N(async (e, s) => {
|
1285
|
+
const n = await r.getById(e.params.id);
|
1286
|
+
if (!n)
|
1287
|
+
return M(s, "Item not found", 404);
|
1288
|
+
R(s, n);
|
1289
|
+
})), t.post("/", N(async (e, s) => {
|
1290
|
+
const n = await r.create(e.body);
|
1291
|
+
R(s, n, "Item created successfully", 201);
|
1292
|
+
})), t.put("/:id", N(async (e, s) => {
|
1293
|
+
const n = await r.update(e.params.id, e.body);
|
1294
|
+
if (!n)
|
1295
|
+
return M(s, "Item not found", 404);
|
1296
|
+
R(s, n, "Item updated successfully");
|
1297
|
+
})), t.delete("/:id", N(async (e, s) => {
|
1298
|
+
if (!await r.delete(e.params.id))
|
1299
|
+
return M(s, "Item not found", 404);
|
1300
|
+
R(s, null, "Item deleted successfully");
|
1301
|
+
})), t;
|
1302
|
+
}
|
1303
|
+
const wt = {
|
1606
1304
|
// Frontend
|
1607
|
-
jsx,
|
1608
|
-
jsxs,
|
1609
|
-
createElement:
|
1610
|
-
Fragment,
|
1611
|
-
Component,
|
1612
|
-
useState,
|
1613
|
-
useEffect,
|
1614
|
-
useRef,
|
1615
|
-
useMemo,
|
1616
|
-
useErrorBoundary,
|
1617
|
-
render,
|
1618
|
-
hydrate,
|
1619
|
-
renderToString,
|
1620
|
-
prepareRender,
|
1621
|
-
finishRender,
|
1622
|
-
batchUpdates,
|
1305
|
+
jsx: ae,
|
1306
|
+
jsxs: Te,
|
1307
|
+
createElement: se,
|
1308
|
+
Fragment: ke,
|
1309
|
+
Component: We,
|
1310
|
+
useState: Ae,
|
1311
|
+
useEffect: Ue,
|
1312
|
+
useRef: Ge,
|
1313
|
+
useMemo: qe,
|
1314
|
+
useErrorBoundary: Je,
|
1315
|
+
render: ue,
|
1316
|
+
hydrate: Qe,
|
1317
|
+
renderToString: P,
|
1318
|
+
prepareRender: U,
|
1319
|
+
finishRender: q,
|
1320
|
+
batchUpdates: ce,
|
1321
|
+
createContext: Xe,
|
1322
|
+
useContext: Ze,
|
1623
1323
|
// Backend
|
1624
|
-
createServer,
|
1625
|
-
|
1626
|
-
|
1324
|
+
createServer: Ke,
|
1325
|
+
createAuth: tt,
|
1326
|
+
createModel: rt,
|
1327
|
+
FieldTypes: st,
|
1328
|
+
createModelRouter: nt,
|
1329
|
+
createCustomRouter: ot,
|
1330
|
+
createApiRouter: at,
|
1331
|
+
sendSuccess: R,
|
1332
|
+
sendError: M,
|
1333
|
+
apiResponse: le,
|
1334
|
+
getPaginationParams: $e,
|
1335
|
+
paginationMiddleware: je,
|
1336
|
+
validateRequest: it,
|
1337
|
+
asyncHandler: N,
|
1338
|
+
createRestEndpoints: ct,
|
1339
|
+
DatabaseConnector: xe
|
1627
1340
|
};
|
1628
1341
|
export {
|
1629
|
-
Component,
|
1630
|
-
DatabaseConnector,
|
1631
|
-
FieldTypes,
|
1632
|
-
Fragment,
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1640
|
-
|
1641
|
-
createModel,
|
1642
|
-
createModelRouter,
|
1643
|
-
createRestEndpoints,
|
1644
|
-
createServer,
|
1645
|
-
|
1646
|
-
finishRender,
|
1647
|
-
getPaginationParams,
|
1648
|
-
hydrate,
|
1649
|
-
jsx,
|
1650
|
-
jsxs,
|
1651
|
-
paginationMiddleware,
|
1652
|
-
prepareRender,
|
1653
|
-
render,
|
1654
|
-
renderToString,
|
1655
|
-
sendError,
|
1656
|
-
sendSuccess,
|
1657
|
-
|
1658
|
-
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1342
|
+
We as Component,
|
1343
|
+
xe as DatabaseConnector,
|
1344
|
+
st as FieldTypes,
|
1345
|
+
ke as Fragment,
|
1346
|
+
le as apiResponse,
|
1347
|
+
N as asyncHandler,
|
1348
|
+
ce as batchUpdates,
|
1349
|
+
at as createApiRouter,
|
1350
|
+
tt as createAuth,
|
1351
|
+
Xe as createContext,
|
1352
|
+
ot as createCustomRouter,
|
1353
|
+
se as createElement,
|
1354
|
+
rt as createModel,
|
1355
|
+
nt as createModelRouter,
|
1356
|
+
ct as createRestEndpoints,
|
1357
|
+
Ke as createServer,
|
1358
|
+
wt as default,
|
1359
|
+
q as finishRender,
|
1360
|
+
$e as getPaginationParams,
|
1361
|
+
Qe as hydrate,
|
1362
|
+
ae as jsx,
|
1363
|
+
Te as jsxs,
|
1364
|
+
je as paginationMiddleware,
|
1365
|
+
U as prepareRender,
|
1366
|
+
ue as render,
|
1367
|
+
P as renderToString,
|
1368
|
+
M as sendError,
|
1369
|
+
R as sendSuccess,
|
1370
|
+
Ze as useContext,
|
1371
|
+
Ue as useEffect,
|
1372
|
+
Je as useErrorBoundary,
|
1373
|
+
qe as useMemo,
|
1374
|
+
Ge as useRef,
|
1375
|
+
Ae as useState,
|
1376
|
+
it as validateRequest
|
1663
1377
|
};
|
1664
|
-
//# sourceMappingURL=frontend-hamroun.es.js.map
|