@forgedevstack/harbor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +927 -0
  3. package/dist/changelog/index.d.ts +3 -0
  4. package/dist/changelog/index.d.ts.map +1 -0
  5. package/dist/changelog/manager.d.ts +29 -0
  6. package/dist/changelog/manager.d.ts.map +1 -0
  7. package/dist/changelog/types.d.ts +41 -0
  8. package/dist/changelog/types.d.ts.map +1 -0
  9. package/dist/cli/index.d.ts +3 -0
  10. package/dist/cli/index.d.ts.map +1 -0
  11. package/dist/cli/index.js +43 -0
  12. package/dist/cli/index.js.map +1 -0
  13. package/dist/constants/config.const.d.ts +11 -0
  14. package/dist/constants/config.const.d.ts.map +1 -0
  15. package/dist/constants/defaults.const.d.ts +10 -0
  16. package/dist/constants/defaults.const.d.ts.map +1 -0
  17. package/dist/constants/http.const.d.ts +43 -0
  18. package/dist/constants/http.const.d.ts.map +1 -0
  19. package/dist/constants/index.d.ts +5 -0
  20. package/dist/constants/index.d.ts.map +1 -0
  21. package/dist/constants/validation.const.d.ts +35 -0
  22. package/dist/constants/validation.const.d.ts.map +1 -0
  23. package/dist/core/config.d.ts +6 -0
  24. package/dist/core/config.d.ts.map +1 -0
  25. package/dist/core/errorHandler.d.ts +25 -0
  26. package/dist/core/errorHandler.d.ts.map +1 -0
  27. package/dist/core/index.d.ts +6 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/router.d.ts +68 -0
  30. package/dist/core/router.d.ts.map +1 -0
  31. package/dist/core/server.d.ts +4 -0
  32. package/dist/core/server.d.ts.map +1 -0
  33. package/dist/database/connection.d.ts +39 -0
  34. package/dist/database/connection.d.ts.map +1 -0
  35. package/dist/database/index.d.ts +28 -0
  36. package/dist/database/index.d.ts.map +1 -0
  37. package/dist/database/model.d.ts +118 -0
  38. package/dist/database/model.d.ts.map +1 -0
  39. package/dist/database/schema.d.ts +63 -0
  40. package/dist/database/schema.d.ts.map +1 -0
  41. package/dist/database/types.d.ts +270 -0
  42. package/dist/database/types.d.ts.map +1 -0
  43. package/dist/docker/index.d.ts +3 -0
  44. package/dist/docker/index.d.ts.map +1 -0
  45. package/dist/docker/index.js +2 -0
  46. package/dist/docker/index.js.map +1 -0
  47. package/dist/docker/manager.d.ts +21 -0
  48. package/dist/docker/manager.d.ts.map +1 -0
  49. package/dist/i18n/index.d.ts +38 -0
  50. package/dist/i18n/index.d.ts.map +1 -0
  51. package/dist/i18n/locales/en.d.ts +2 -0
  52. package/dist/i18n/locales/en.d.ts.map +1 -0
  53. package/dist/i18n/locales/he.d.ts +2 -0
  54. package/dist/i18n/locales/he.d.ts.map +1 -0
  55. package/dist/index.cjs.js +24 -0
  56. package/dist/index.cjs.js.map +1 -0
  57. package/dist/index.d.ts +21 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.es.js +2094 -0
  60. package/dist/index.es.js.map +1 -0
  61. package/dist/logger-D7aJSi62.mjs +102 -0
  62. package/dist/logger-D7aJSi62.mjs.map +1 -0
  63. package/dist/logger-DEnWXtpk.js +3 -0
  64. package/dist/logger-DEnWXtpk.js.map +1 -0
  65. package/dist/manager-B1UKMjXW.js +4 -0
  66. package/dist/manager-B1UKMjXW.js.map +1 -0
  67. package/dist/manager-B6vqJgEn.mjs +152 -0
  68. package/dist/manager-B6vqJgEn.mjs.map +1 -0
  69. package/dist/portal.d.ts +13 -0
  70. package/dist/portal.d.ts.map +1 -0
  71. package/dist/types/config.types.d.ts +83 -0
  72. package/dist/types/config.types.d.ts.map +1 -0
  73. package/dist/types/docker.types.d.ts +92 -0
  74. package/dist/types/docker.types.d.ts.map +1 -0
  75. package/dist/types/index.d.ts +7 -0
  76. package/dist/types/index.d.ts.map +1 -0
  77. package/dist/types/logger.types.d.ts +35 -0
  78. package/dist/types/logger.types.d.ts.map +1 -0
  79. package/dist/types/route.types.d.ts +78 -0
  80. package/dist/types/route.types.d.ts.map +1 -0
  81. package/dist/types/server.types.d.ts +67 -0
  82. package/dist/types/server.types.d.ts.map +1 -0
  83. package/dist/types/validation.types.d.ts +64 -0
  84. package/dist/types/validation.types.d.ts.map +1 -0
  85. package/dist/utils/helpers.d.ts +7 -0
  86. package/dist/utils/helpers.d.ts.map +1 -0
  87. package/dist/utils/httpLogger.d.ts +52 -0
  88. package/dist/utils/httpLogger.d.ts.map +1 -0
  89. package/dist/utils/index.d.ts +6 -0
  90. package/dist/utils/index.d.ts.map +1 -0
  91. package/dist/utils/logger.d.ts +6 -0
  92. package/dist/utils/logger.d.ts.map +1 -0
  93. package/dist/utils/object.d.ts +6 -0
  94. package/dist/utils/object.d.ts.map +1 -0
  95. package/dist/validation/index.d.ts +5 -0
  96. package/dist/validation/index.d.ts.map +1 -0
  97. package/dist/validation/index.js +2 -0
  98. package/dist/validation/index.js.map +1 -0
  99. package/dist/validation/mongo.d.ts +13 -0
  100. package/dist/validation/mongo.d.ts.map +1 -0
  101. package/dist/validation/paramValidators.d.ts +18 -0
  102. package/dist/validation/paramValidators.d.ts.map +1 -0
  103. package/dist/validation/validators.d.ts +9 -0
  104. package/dist/validation/validators.d.ts.map +1 -0
  105. package/harbor.config.example.json +72 -0
  106. package/package.json +107 -0
  107. package/templates/default/.eslintrc.json +45 -0
  108. package/templates/default/README.md +97 -0
  109. package/templates/default/constants/config.ts +26 -0
  110. package/templates/default/constants/http.ts +32 -0
  111. package/templates/default/constants/index.ts +3 -0
  112. package/templates/default/controllers/index.ts +6 -0
  113. package/templates/default/controllers/user.controller.ts +77 -0
  114. package/templates/default/env.example +22 -0
  115. package/templates/default/harbor.version.json +7 -0
  116. package/templates/default/models/index.ts +6 -0
  117. package/templates/default/models/user.model.ts +68 -0
  118. package/templates/default/package.json +44 -0
  119. package/templates/default/routes/index.ts +12 -0
  120. package/templates/default/routes/user.routes.ts +21 -0
  121. package/templates/default/server.ts +45 -0
  122. package/templates/default/services/index.ts +6 -0
  123. package/templates/default/services/user.service.ts +84 -0
  124. package/templates/default/tsconfig.json +35 -0
  125. package/templates/default/types/index.ts +57 -0
  126. package/templates/default/utils/asyncHandler.ts +14 -0
  127. package/templates/default/utils/index.ts +5 -0
  128. package/templates/default/utils/logger.ts +52 -0
  129. package/templates/default/utils/response.ts +24 -0
  130. package/templates/default/utils/validation.ts +23 -0
@@ -0,0 +1,2094 @@
1
+ var ee = Object.defineProperty;
2
+ var te = (r, e, t) => e in r ? ee(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var c = (r, e, t) => te(r, typeof e != "symbol" ? e + "" : e, t);
4
+ import q, { Router as ne } from "express";
5
+ import { createServer as re } from "http";
6
+ import { readFileSync as X, existsSync as I, writeFileSync as se } from "fs";
7
+ import { resolve as R } from "path";
8
+ import { c as A } from "./logger-D7aJSi62.mjs";
9
+ import { s as kt } from "./logger-D7aJSi62.mjs";
10
+ import { validateRequest as F } from "./validation/index.js";
11
+ import { MongoValidator as Ht, createMongoSchema as Nt, createParamValidator as It, validateField as xt, validators as Dt } from "./validation/index.js";
12
+ import { EventEmitter as oe } from "events";
13
+ import { ObjectId as v } from "mongodb";
14
+ import { D as jt, c as Lt } from "./manager-B6vqJgEn.mjs";
15
+ const ie = [
16
+ "./harbor.config.json",
17
+ "./config/harbor.config.json",
18
+ "./.harbor/config.json"
19
+ ], x = {
20
+ PORT: "HARBOR_PORT",
21
+ HOST: "HARBOR_HOST",
22
+ LOG_LEVEL: "HARBOR_LOG_LEVEL",
23
+ CONFIG_PATH: "HARBOR_CONFIG_PATH"
24
+ }, Xe = {
25
+ GET: "GET",
26
+ POST: "POST",
27
+ PUT: "PUT",
28
+ PATCH: "PATCH",
29
+ DELETE: "DELETE",
30
+ OPTIONS: "OPTIONS",
31
+ HEAD: "HEAD"
32
+ }, p = {
33
+ OK: 200,
34
+ CREATED: 201,
35
+ NO_CONTENT: 204,
36
+ BAD_REQUEST: 400,
37
+ UNAUTHORIZED: 401,
38
+ FORBIDDEN: 403,
39
+ NOT_FOUND: 404,
40
+ METHOD_NOT_ALLOWED: 405,
41
+ CONFLICT: 409,
42
+ UNPROCESSABLE_ENTITY: 422,
43
+ TOO_MANY_REQUESTS: 429,
44
+ INTERNAL_SERVER_ERROR: 500,
45
+ BAD_GATEWAY: 502,
46
+ SERVICE_UNAVAILABLE: 503,
47
+ GATEWAY_TIMEOUT: 504
48
+ }, ae = {
49
+ 200: "OK",
50
+ 201: "Created",
51
+ 204: "No Content",
52
+ 400: "Bad Request",
53
+ 401: "Unauthorized",
54
+ 403: "Forbidden",
55
+ 404: "Not Found",
56
+ 405: "Method Not Allowed",
57
+ 409: "Conflict",
58
+ 422: "Unprocessable Entity",
59
+ 429: "Too Many Requests",
60
+ 500: "Internal Server Error",
61
+ 502: "Bad Gateway",
62
+ 503: "Service Unavailable",
63
+ 504: "Gateway Timeout"
64
+ }, Je = {
65
+ JSON: "application/json",
66
+ HTML: "text/html",
67
+ TEXT: "text/plain",
68
+ FORM: "application/x-www-form-urlencoded",
69
+ MULTIPART: "multipart/form-data"
70
+ }, Ze = {
71
+ CONTENT_TYPE: "Content-Type",
72
+ AUTHORIZATION: "Authorization",
73
+ ACCEPT: "Accept",
74
+ CACHE_CONTROL: "Cache-Control",
75
+ X_REQUEST_ID: "X-Request-ID",
76
+ X_RESPONSE_TIME: "X-Response-Time"
77
+ }, ce = 3e3, de = "localhost", le = 3e4, ue = "10mb", D = {
78
+ server: {
79
+ port: ce,
80
+ host: de,
81
+ cors: {
82
+ enabled: !0,
83
+ origin: "*",
84
+ methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
85
+ credentials: !1
86
+ },
87
+ bodyParser: {
88
+ json: !0,
89
+ urlencoded: !0,
90
+ limit: ue
91
+ },
92
+ trustProxy: !1
93
+ },
94
+ routes: {
95
+ prefix: "",
96
+ timeout: le,
97
+ defaultMiddleware: []
98
+ },
99
+ validation: {
100
+ adapter: "mongoose",
101
+ strictMode: !0,
102
+ sanitize: !0
103
+ },
104
+ errors: {
105
+ 400: {
106
+ message: "Bad Request",
107
+ json: !0,
108
+ log: !1
109
+ },
110
+ 401: {
111
+ message: "Unauthorized",
112
+ json: !0,
113
+ log: !0
114
+ },
115
+ 403: {
116
+ message: "Forbidden",
117
+ json: !0,
118
+ log: !0
119
+ },
120
+ 404: {
121
+ message: "Not Found",
122
+ json: !0,
123
+ log: !1
124
+ },
125
+ 500: {
126
+ message: "Internal Server Error",
127
+ json: !0,
128
+ log: !0
129
+ },
130
+ default: {
131
+ message: "An error occurred",
132
+ json: !0,
133
+ log: !0
134
+ }
135
+ },
136
+ logger: {
137
+ enabled: !0,
138
+ level: "info",
139
+ format: "text",
140
+ output: "console"
141
+ }
142
+ }, he = 1e4, B = A("config");
143
+ function me(r) {
144
+ const e = fe(r);
145
+ if (!e)
146
+ return B.info("No config file found, using defaults"), V(D);
147
+ try {
148
+ const t = X(e, "utf-8"), n = JSON.parse(t), s = z(
149
+ D,
150
+ n
151
+ );
152
+ return B.info("Config loaded", { path: e }), V(s);
153
+ } catch (t) {
154
+ return B.error("Failed to load config", t), V(D);
155
+ }
156
+ }
157
+ function et(r) {
158
+ return z(
159
+ D,
160
+ r
161
+ );
162
+ }
163
+ function fe(r) {
164
+ if (r) {
165
+ const t = R(process.cwd(), r);
166
+ return I(t) ? t : null;
167
+ }
168
+ const e = process.env[x.CONFIG_PATH];
169
+ if (e) {
170
+ const t = R(process.cwd(), e);
171
+ if (I(t))
172
+ return t;
173
+ }
174
+ for (const t of ie) {
175
+ const n = R(process.cwd(), t);
176
+ if (I(n))
177
+ return n;
178
+ }
179
+ return null;
180
+ }
181
+ function V(r) {
182
+ const e = process.env[x.PORT], t = process.env[x.HOST], n = process.env[x.LOG_LEVEL];
183
+ return e && (r.server.port = parseInt(e, 10)), t && (r.server.host = t), n && (r.logger.level = n), r;
184
+ }
185
+ function z(r, e) {
186
+ const t = { ...r };
187
+ for (const n in e)
188
+ if (Object.prototype.hasOwnProperty.call(e, n)) {
189
+ const s = e[n], o = r[n];
190
+ s !== null && typeof s == "object" && !Array.isArray(s) && o !== null && typeof o == "object" && !Array.isArray(o) ? t[n] = z(
191
+ o,
192
+ s
193
+ ) : s !== void 0 && (t[n] = s);
194
+ }
195
+ return t;
196
+ }
197
+ const ge = {
198
+ // Server
199
+ "server.starting": "Server starting...",
200
+ "server.started": "Server started on http://{host}:{port}",
201
+ "server.stopping": "Server stopping...",
202
+ "server.stopped": "Server stopped",
203
+ "server.alreadyRunning": "Server is already running",
204
+ "server.error": "Server error",
205
+ "server.gracefulShutdown": "Received {signal}, shutting down gracefully",
206
+ // Router
207
+ "router.registered": "Registered route: {method} {path}",
208
+ "router.missingRequired": "Route must have path, method, and handler",
209
+ // Validation
210
+ "validation.failed": "Validation failed",
211
+ "validation.required": "{field} is required",
212
+ "validation.typeMismatch": "{field} must be of type {type}",
213
+ "validation.minValue": "{field} must be at least {min}",
214
+ "validation.maxValue": "{field} must be at most {max}",
215
+ "validation.minLength": "{field} must be at least {min} characters",
216
+ "validation.maxLength": "{field} must be at most {max} characters",
217
+ "validation.pattern": "{field} does not match the required pattern",
218
+ "validation.enum": "{field} must be one of: {values}",
219
+ "validation.invalidObjectId": "{field} is not a valid ObjectId",
220
+ "validation.invalidEmail": "{field} is not a valid email address",
221
+ "validation.invalidUrl": "{field} is not a valid URL",
222
+ "validation.invalidDate": "{field} is not a valid date",
223
+ "validation.customFailed": "{field} failed custom validation",
224
+ // Errors
225
+ "errors.badRequest": "Bad Request",
226
+ "errors.unauthorized": "Unauthorized",
227
+ "errors.forbidden": "Forbidden",
228
+ "errors.notFound": "Not Found",
229
+ "errors.conflict": "Conflict",
230
+ "errors.tooManyRequests": "Too Many Requests",
231
+ "errors.internal": "Internal Server Error",
232
+ "errors.timeout": "Request timeout",
233
+ "errors.default": "An error occurred",
234
+ // Config
235
+ "config.notFound": "No config file found, using defaults",
236
+ "config.loaded": "Config loaded from {path}",
237
+ "config.loadFailed": "Failed to load config",
238
+ // Docker
239
+ "docker.containerStarted": "Container started: {name}",
240
+ "docker.containerStopped": "Container stopped: {name}",
241
+ "docker.containerRestarted": "Container restarted: {name}",
242
+ "docker.containerRemoved": "Container removed: {name}",
243
+ "docker.imageBuilt": "Image built: {name}:{tag}",
244
+ "docker.imagePushed": "Image pushed: {name}",
245
+ "docker.imagePulled": "Image pulled: {name}:{tag}",
246
+ "docker.composeUp": "Docker Compose up completed",
247
+ "docker.composeDown": "Docker Compose down completed",
248
+ "docker.commandFailed": "Docker command failed: {command}",
249
+ // Changelog
250
+ "changelog.loaded": "Changelog loaded with {count} entries",
251
+ "changelog.saved": "Changelog saved to {path}",
252
+ "changelog.released": "Released version {version}",
253
+ "changelog.notFound": "No changelog file found, starting fresh",
254
+ // Portal
255
+ "portal.generated": "Portal generated at {path}",
256
+ "portal.generating": "Generating documentation portal...",
257
+ // Logger
258
+ "logger.levelChanged": "Log level changed to {level}",
259
+ // HTTP Logger (Morgan-like)
260
+ "http.request": "{method} {url} {status} {duration}ms",
261
+ "http.requestStart": "Incoming request: {method} {url}",
262
+ "http.requestEnd": "Request completed: {method} {url} - {status} in {duration}ms",
263
+ // CLI
264
+ "cli.init.success": "Harbor project initialized!",
265
+ "cli.init.configExists": "harbor.config.json already exists",
266
+ "cli.init.created": "Created {file}",
267
+ "cli.docs.generating": "Generating API documentation...",
268
+ "cli.docs.success": "Documentation generated successfully",
269
+ "cli.version": "Harbor v{version}",
270
+ "cli.unknownCommand": "Unknown command: {command}",
271
+ // Database
272
+ "database.connected": "Connected to MongoDB at {uri}",
273
+ "database.disconnected": "Disconnected from MongoDB",
274
+ "database.connecting": "Connecting to MongoDB...",
275
+ "database.connectionFailed": "Failed to connect to MongoDB: {error}",
276
+ "database.notConnected": "Not connected to database. Call harbor.connect() first.",
277
+ "database.modelCreated": "Model created: {name}",
278
+ "database.documentSaved": "Document saved: {id}",
279
+ "database.documentDeleted": "Document deleted: {id}",
280
+ "database.validationFailed": "Validation failed: {errors}",
281
+ "database.queryExecuted": "Query executed: {operation} on {collection}",
282
+ "database.indexCreated": "Index created: {name}",
283
+ "database.transactionStarted": "Transaction started",
284
+ "database.transactionCommitted": "Transaction committed",
285
+ "database.transactionAborted": "Transaction aborted"
286
+ }, pe = {
287
+ // Server
288
+ "server.starting": "השרת מופעל...",
289
+ "server.started": "השרת פועל בכתובת http://{host}:{port}",
290
+ "server.stopping": "השרת נעצר...",
291
+ "server.stopped": "השרת נעצר",
292
+ "server.alreadyRunning": "השרת כבר פועל",
293
+ "server.error": "שגיאת שרת",
294
+ "server.gracefulShutdown": "התקבל {signal}, מכבה בצורה מסודרת",
295
+ // Router
296
+ "router.registered": "נרשם נתיב: {method} {path}",
297
+ "router.missingRequired": "נתיב חייב לכלול path, method ו-handler",
298
+ // Validation
299
+ "validation.failed": "האימות נכשל",
300
+ "validation.required": "{field} הוא שדה חובה",
301
+ "validation.typeMismatch": "{field} חייב להיות מסוג {type}",
302
+ "validation.minValue": "{field} חייב להיות לפחות {min}",
303
+ "validation.maxValue": "{field} חייב להיות לכל היותר {max}",
304
+ "validation.minLength": "{field} חייב להכיל לפחות {min} תווים",
305
+ "validation.maxLength": "{field} חייב להכיל לכל היותר {max} תווים",
306
+ "validation.pattern": "{field} לא תואם לתבנית הנדרשת",
307
+ "validation.enum": "{field} חייב להיות אחד מ: {values}",
308
+ "validation.invalidObjectId": "{field} אינו ObjectId תקין",
309
+ "validation.invalidEmail": "{field} אינה כתובת אימייל תקינה",
310
+ "validation.invalidUrl": "{field} אינו URL תקין",
311
+ "validation.invalidDate": "{field} אינו תאריך תקין",
312
+ "validation.customFailed": "{field} נכשל באימות מותאם אישית",
313
+ // Errors
314
+ "errors.badRequest": "בקשה שגויה",
315
+ "errors.unauthorized": "לא מורשה",
316
+ "errors.forbidden": "גישה נדחתה",
317
+ "errors.notFound": "לא נמצא",
318
+ "errors.conflict": "התנגשות",
319
+ "errors.tooManyRequests": "יותר מדי בקשות",
320
+ "errors.internal": "שגיאת שרת פנימית",
321
+ "errors.timeout": "הבקשה פגה",
322
+ "errors.default": "אירעה שגיאה",
323
+ // Config
324
+ "config.notFound": "קובץ הגדרות לא נמצא, משתמש בברירת מחדל",
325
+ "config.loaded": "הגדרות נטענו מ-{path}",
326
+ "config.loadFailed": "נכשל בטעינת הגדרות",
327
+ // Docker
328
+ "docker.containerStarted": "קונטיינר הופעל: {name}",
329
+ "docker.containerStopped": "קונטיינר נעצר: {name}",
330
+ "docker.containerRestarted": "קונטיינר הופעל מחדש: {name}",
331
+ "docker.containerRemoved": "קונטיינר הוסר: {name}",
332
+ "docker.imageBuilt": "תמונה נבנתה: {name}:{tag}",
333
+ "docker.imagePushed": "תמונה הועלתה: {name}",
334
+ "docker.imagePulled": "תמונה הורדה: {name}:{tag}",
335
+ "docker.composeUp": "Docker Compose הופעל בהצלחה",
336
+ "docker.composeDown": "Docker Compose נעצר בהצלחה",
337
+ "docker.commandFailed": "פקודת Docker נכשלה: {command}",
338
+ // Changelog
339
+ "changelog.loaded": "יומן שינויים נטען עם {count} רשומות",
340
+ "changelog.saved": "יומן שינויים נשמר ב-{path}",
341
+ "changelog.released": "שוחררה גרסה {version}",
342
+ "changelog.notFound": "קובץ יומן שינויים לא נמצא, מתחיל מחדש",
343
+ // Portal
344
+ "portal.generated": "פורטל נוצר ב-{path}",
345
+ "portal.generating": "מייצר פורטל תיעוד...",
346
+ // Logger
347
+ "logger.levelChanged": "רמת הלוג שונתה ל-{level}",
348
+ // HTTP Logger
349
+ "http.request": "{method} {url} {status} {duration}ms",
350
+ "http.requestStart": "בקשה נכנסת: {method} {url}",
351
+ "http.requestEnd": "בקשה הושלמה: {method} {url} - {status} תוך {duration}ms",
352
+ // CLI
353
+ "cli.init.success": "פרויקט Harbor אותחל בהצלחה!",
354
+ "cli.init.configExists": "harbor.config.json כבר קיים",
355
+ "cli.init.created": "נוצר {file}",
356
+ "cli.docs.generating": "מייצר תיעוד API...",
357
+ "cli.docs.success": "התיעוד נוצר בהצלחה",
358
+ "cli.version": "Harbor גרסה {version}",
359
+ "cli.unknownCommand": "פקודה לא מוכרת: {command}",
360
+ // Database
361
+ "database.connected": "מחובר ל-MongoDB ב-{uri}",
362
+ "database.disconnected": "נותק מ-MongoDB",
363
+ "database.connecting": "מתחבר ל-MongoDB...",
364
+ "database.connectionFailed": "החיבור ל-MongoDB נכשל: {error}",
365
+ "database.notConnected": "לא מחובר למסד נתונים. קרא ל-harbor.connect() קודם.",
366
+ "database.modelCreated": "מודל נוצר: {name}",
367
+ "database.documentSaved": "מסמך נשמר: {id}",
368
+ "database.documentDeleted": "מסמך נמחק: {id}",
369
+ "database.validationFailed": "האימות נכשל: {errors}",
370
+ "database.queryExecuted": "שאילתה בוצעה: {operation} על {collection}",
371
+ "database.indexCreated": "אינדקס נוצר: {name}",
372
+ "database.transactionStarted": "טרנזקציה התחילה",
373
+ "database.transactionCommitted": "טרנזקציה אושרה",
374
+ "database.transactionAborted": "טרנזקציה בוטלה"
375
+ }, E = {
376
+ en: ge,
377
+ he: pe
378
+ };
379
+ let M = "en";
380
+ function tt(r) {
381
+ if (!E[r]) {
382
+ console.warn(`Locale "${r}" not found, falling back to "en"`), M = "en";
383
+ return;
384
+ }
385
+ M = r;
386
+ }
387
+ function nt() {
388
+ return M;
389
+ }
390
+ function rt() {
391
+ return Object.keys(E);
392
+ }
393
+ function C(r, e) {
394
+ let n = (E[M] ?? E.en)[r] ?? E.en[r] ?? r;
395
+ if (e)
396
+ for (const [s, o] of Object.entries(e))
397
+ n = n.replace(new RegExp(`{${s}}`, "g"), String(o ?? ""));
398
+ return n;
399
+ }
400
+ function st(r, e) {
401
+ E[r] || (E[r] = {}), Object.assign(E[r], e);
402
+ }
403
+ function ot(r, e) {
404
+ E[r] = e;
405
+ }
406
+ const _e = A("router");
407
+ function K(r, e) {
408
+ const t = ne();
409
+ return r.middleware && r.middleware.forEach((n) => t.use(n)), r.routes && r.routes.forEach((n) => {
410
+ ye(t, n, e);
411
+ }), t;
412
+ }
413
+ function ye(r, e, t) {
414
+ const n = e.method.toLowerCase(), s = we(e, t);
415
+ r[n](e.path, ...s), _e.debug(C("router.registered", { method: e.method, path: e.path }));
416
+ }
417
+ function we(r, e) {
418
+ const t = [], n = r.options ?? {};
419
+ return n.pre && n.pre.forEach((s) => {
420
+ t.push(ve(s));
421
+ }), n.validation && t.push(Ce(n.validation, e)), n.timeout && t.push(Te(n.timeout)), t.push(be(r.handler, n)), t;
422
+ }
423
+ function ve(r) {
424
+ return async (e, t, n) => {
425
+ try {
426
+ await r(e, t, n);
427
+ } catch (s) {
428
+ n(s);
429
+ }
430
+ };
431
+ }
432
+ function be(r, e) {
433
+ return async (t, n, s) => {
434
+ try {
435
+ const o = await r(t, n);
436
+ if (e.post && e.post.length > 0)
437
+ for (const i of e.post)
438
+ await i(t, n, o);
439
+ !n.headersSent && o !== void 0 && n.json({
440
+ success: !0,
441
+ data: o
442
+ });
443
+ } catch (o) {
444
+ s(o);
445
+ }
446
+ };
447
+ }
448
+ function Ce(r, e) {
449
+ return async (t, n, s) => {
450
+ try {
451
+ const o = {};
452
+ if (r.params) {
453
+ const i = await F(r.params, t.params, e.validation);
454
+ if (!i.valid) {
455
+ n.status(p.BAD_REQUEST).json({
456
+ success: !1,
457
+ error: {
458
+ message: C("validation.failed"),
459
+ details: i.errors
460
+ }
461
+ });
462
+ return;
463
+ }
464
+ o.params = i.data;
465
+ }
466
+ if (r.query) {
467
+ const i = await F(r.query, t.query, e.validation);
468
+ if (!i.valid) {
469
+ n.status(p.BAD_REQUEST).json({
470
+ success: !1,
471
+ error: {
472
+ message: C("validation.failed"),
473
+ details: i.errors
474
+ }
475
+ });
476
+ return;
477
+ }
478
+ o.query = i.data;
479
+ }
480
+ if (r.body) {
481
+ const i = await F(r.body, t.body, e.validation);
482
+ if (!i.valid) {
483
+ n.status(p.BAD_REQUEST).json({
484
+ success: !1,
485
+ error: {
486
+ message: C("validation.failed"),
487
+ details: i.errors
488
+ }
489
+ });
490
+ return;
491
+ }
492
+ o.body = i.data;
493
+ }
494
+ t.validated = o, s();
495
+ } catch (o) {
496
+ s(o);
497
+ }
498
+ };
499
+ }
500
+ function Te(r) {
501
+ return (e, t, n) => {
502
+ const s = setTimeout(() => {
503
+ t.headersSent || t.status(p.GATEWAY_TIMEOUT).json({
504
+ success: !1,
505
+ error: {
506
+ message: C("errors.timeout")
507
+ }
508
+ });
509
+ }, r);
510
+ t.on("finish", () => clearTimeout(s)), t.on("close", () => clearTimeout(s)), n();
511
+ };
512
+ }
513
+ function it(r, e, t) {
514
+ return P("GET", r, e, t);
515
+ }
516
+ function at(r, e, t) {
517
+ return P("POST", r, e, t);
518
+ }
519
+ function ct(r, e, t) {
520
+ return P("PUT", r, e, t);
521
+ }
522
+ function dt(r, e, t) {
523
+ return P("PATCH", r, e, t);
524
+ }
525
+ function lt(r, e, t) {
526
+ return P("DELETE", r, e, t);
527
+ }
528
+ function ut(r, e, t, n) {
529
+ return P(r, e, t, n);
530
+ }
531
+ function P(r, e, t, n) {
532
+ return {
533
+ path: e,
534
+ method: r,
535
+ handler: t,
536
+ options: n ? {
537
+ pre: n.pre,
538
+ post: n.post,
539
+ validation: n.validation,
540
+ timeout: n.timeout
541
+ } : void 0
542
+ };
543
+ }
544
+ class J {
545
+ constructor() {
546
+ c(this, "_route", {});
547
+ c(this, "_options", {});
548
+ }
549
+ static create() {
550
+ return new J();
551
+ }
552
+ path(e) {
553
+ return this._route.path = e, this;
554
+ }
555
+ method(e) {
556
+ return this._route.method = e, this;
557
+ }
558
+ get(e) {
559
+ return this.method("GET").path(e);
560
+ }
561
+ post(e) {
562
+ return this.method("POST").path(e);
563
+ }
564
+ put(e) {
565
+ return this.method("PUT").path(e);
566
+ }
567
+ patch(e) {
568
+ return this.method("PATCH").path(e);
569
+ }
570
+ delete(e) {
571
+ return this.method("DELETE").path(e);
572
+ }
573
+ handler(e) {
574
+ if (this._route.handler = e, !this._route.path || !this._route.method || !this._route.handler)
575
+ throw new Error(C("router.missingRequired"));
576
+ return {
577
+ path: this._route.path,
578
+ method: this._route.method,
579
+ handler: this._route.handler,
580
+ options: Object.keys(this._options).length > 0 ? this._options : void 0
581
+ };
582
+ }
583
+ pre(...e) {
584
+ return this._options.pre = [...this._options.pre ?? [], ...e], this;
585
+ }
586
+ postFn(...e) {
587
+ return this._options.post = [...this._options.post ?? [], ...e], this;
588
+ }
589
+ validate(e) {
590
+ return this._options.validation = e, this;
591
+ }
592
+ timeout(e) {
593
+ return this._options.timeout = e, this;
594
+ }
595
+ rateLimit(e) {
596
+ return this._options.rateLimit = e, this;
597
+ }
598
+ auth(e) {
599
+ return this._options.auth = e, this;
600
+ }
601
+ cache(e) {
602
+ return this._options.cache = e, this;
603
+ }
604
+ // Legacy .build() still works for backwards compatibility
605
+ build() {
606
+ if (!this._route.path || !this._route.method || !this._route.handler)
607
+ throw new Error(C("router.missingRequired"));
608
+ return {
609
+ path: this._route.path,
610
+ method: this._route.method,
611
+ handler: this._route.handler,
612
+ options: Object.keys(this._options).length > 0 ? this._options : void 0
613
+ };
614
+ }
615
+ }
616
+ const Oe = A("error");
617
+ class O extends Error {
618
+ constructor(t, n = p.INTERNAL_SERVER_ERROR, s) {
619
+ super(t);
620
+ c(this, "statusCode");
621
+ c(this, "code");
622
+ c(this, "details");
623
+ c(this, "isOperational");
624
+ this.name = "HarborError", this.statusCode = n, this.code = s == null ? void 0 : s.code, this.details = s == null ? void 0 : s.details, this.isOperational = (s == null ? void 0 : s.isOperational) ?? !0, Error.captureStackTrace(this, this.constructor);
625
+ }
626
+ static badRequest(t, n) {
627
+ return new O(
628
+ t ?? "Bad Request",
629
+ p.BAD_REQUEST,
630
+ { code: "BAD_REQUEST", details: n }
631
+ );
632
+ }
633
+ static unauthorized(t) {
634
+ return new O(
635
+ t ?? "Unauthorized",
636
+ p.UNAUTHORIZED,
637
+ { code: "UNAUTHORIZED" }
638
+ );
639
+ }
640
+ static forbidden(t) {
641
+ return new O(
642
+ t ?? "Forbidden",
643
+ p.FORBIDDEN,
644
+ { code: "FORBIDDEN" }
645
+ );
646
+ }
647
+ static notFound(t) {
648
+ return new O(
649
+ t ?? "Not Found",
650
+ p.NOT_FOUND,
651
+ { code: "NOT_FOUND" }
652
+ );
653
+ }
654
+ static conflict(t, n) {
655
+ return new O(
656
+ t ?? "Conflict",
657
+ p.CONFLICT,
658
+ { code: "CONFLICT", details: n }
659
+ );
660
+ }
661
+ static internal(t) {
662
+ return new O(
663
+ t ?? "Internal Server Error",
664
+ p.INTERNAL_SERVER_ERROR,
665
+ { code: "INTERNAL_ERROR", isOperational: !1 }
666
+ );
667
+ }
668
+ static tooManyRequests(t) {
669
+ return new O(
670
+ t ?? "Too Many Requests",
671
+ p.TOO_MANY_REQUESTS,
672
+ { code: "RATE_LIMIT_EXCEEDED" }
673
+ );
674
+ }
675
+ toJSON() {
676
+ return {
677
+ success: !1,
678
+ error: {
679
+ message: this.message,
680
+ code: this.code,
681
+ statusCode: this.statusCode,
682
+ details: this.details
683
+ }
684
+ };
685
+ }
686
+ }
687
+ function Ee(r) {
688
+ const e = r.errors;
689
+ return (t, n, s, o) => {
690
+ const i = t.statusCode ?? p.INTERNAL_SERVER_ERROR, a = Se(i, e);
691
+ if ((a == null ? void 0 : a.log) !== !1 && r.logger.enabled && Oe.error(`${n.method} ${n.path} - ${t.message}`, t), s.headersSent)
692
+ return;
693
+ if (a != null && a.redirect) {
694
+ s.redirect(a.redirect);
695
+ return;
696
+ }
697
+ const h = Ae(t, i, a);
698
+ (a == null ? void 0 : a.json) !== !1 ? s.status(i).json(h) : s.status(i).send(h.error.message);
699
+ };
700
+ }
701
+ function Se(r, e) {
702
+ const t = r.toString();
703
+ return e[t] ?? e.default;
704
+ }
705
+ function Ae(r, e, t) {
706
+ return r instanceof O ? r.toJSON() : {
707
+ success: !1,
708
+ error: {
709
+ message: (t == null ? void 0 : t.message) ?? r.message ?? ae[e] ?? "An error occurred",
710
+ statusCode: e
711
+ }
712
+ };
713
+ }
714
+ const S = A("server");
715
+ function ht(r = {}) {
716
+ const e = me(r.configPath), t = q();
717
+ let n = null, s = "stopped", o = null;
718
+ const i = [];
719
+ Pe(t, e);
720
+ const a = {
721
+ app: t,
722
+ server: n,
723
+ config: e,
724
+ async start() {
725
+ if (s === "running")
726
+ return S.warn("Server is already running"), a.getInfo();
727
+ s = "starting";
728
+ const h = r.port ?? e.server.port, g = r.host ?? e.server.host ?? "localhost";
729
+ return new Promise((w, b) => {
730
+ try {
731
+ n = re(t), a.server = n, n.listen(h, g, () => {
732
+ var l;
733
+ s = "running", o = /* @__PURE__ */ new Date();
734
+ const d = a.getInfo();
735
+ S.info(`Server started on http://${g}:${h}`), (l = r.onReady) == null || l.call(r, d), w(d);
736
+ }), n.on("error", (d) => {
737
+ var l;
738
+ s = "error", S.error("Server error", d), (l = r.onError) == null || l.call(r, d), b(d);
739
+ }), Re(a);
740
+ } catch (d) {
741
+ s = "error", b(d);
742
+ }
743
+ });
744
+ },
745
+ async stop() {
746
+ if (!(!n || s === "stopped"))
747
+ return s = "stopping", new Promise((h, g) => {
748
+ const w = setTimeout(() => {
749
+ n == null || n.close(), h();
750
+ }, he);
751
+ n.close((b) => {
752
+ clearTimeout(w), b ? (S.error("Error stopping server", b), g(b)) : (s = "stopped", o = null, S.info("Server stopped"), h());
753
+ });
754
+ });
755
+ },
756
+ async restart() {
757
+ return await a.stop(), a.start();
758
+ },
759
+ addRoute(h) {
760
+ i.push(h);
761
+ const g = K({ routes: [h] }, e);
762
+ t.use(g);
763
+ },
764
+ addRouteGroup(h) {
765
+ i.push(...h.routes);
766
+ const g = K({
767
+ prefix: h.prefix,
768
+ routes: h.routes,
769
+ middleware: h.middleware
770
+ }, e);
771
+ t.use(h.prefix, g);
772
+ },
773
+ addMiddleware(h) {
774
+ t.use(h);
775
+ },
776
+ getInfo() {
777
+ const h = r.port ?? e.server.port, g = r.host ?? e.server.host ?? "localhost";
778
+ return {
779
+ port: h,
780
+ host: g,
781
+ uptime: o ? Date.now() - o.getTime() : 0,
782
+ startedAt: o,
783
+ routes: i.map((w) => ({
784
+ path: w.path,
785
+ method: w.method,
786
+ middleware: []
787
+ })),
788
+ status: s
789
+ };
790
+ }
791
+ };
792
+ return r.autoStart !== !1 && a.start().catch((h) => {
793
+ S.error("Failed to auto-start server", h);
794
+ }), a;
795
+ }
796
+ function Pe(r, e) {
797
+ var n, s, o;
798
+ (n = e.server.bodyParser) != null && n.json && r.use(q.json({ limit: e.server.bodyParser.limit })), (s = e.server.bodyParser) != null && s.urlencoded && r.use(q.urlencoded({
799
+ extended: !0,
800
+ limit: e.server.bodyParser.limit
801
+ })), (o = e.server.cors) != null && o.enabled && r.use($e(e.server.cors)), r.use(ke());
802
+ const t = Ee(e);
803
+ r.use(t);
804
+ }
805
+ function $e(r) {
806
+ return (e, t, n) => {
807
+ var o;
808
+ const s = r.origin;
809
+ if (s === !0 || s === "*")
810
+ t.setHeader("Access-Control-Allow-Origin", "*");
811
+ else if (typeof s == "string")
812
+ t.setHeader("Access-Control-Allow-Origin", s);
813
+ else if (Array.isArray(s)) {
814
+ const i = e.headers.origin;
815
+ i && s.includes(i) && t.setHeader("Access-Control-Allow-Origin", i);
816
+ }
817
+ if (t.setHeader(
818
+ "Access-Control-Allow-Methods",
819
+ ((o = r.methods) == null ? void 0 : o.join(", ")) ?? "GET,POST,PUT,PATCH,DELETE,OPTIONS"
820
+ ), r.allowedHeaders ? t.setHeader("Access-Control-Allow-Headers", r.allowedHeaders.join(", ")) : t.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"), r.credentials && t.setHeader("Access-Control-Allow-Credentials", "true"), e.method === "OPTIONS") {
821
+ t.status(204).end();
822
+ return;
823
+ }
824
+ n();
825
+ };
826
+ }
827
+ function ke() {
828
+ return (r, e, t) => {
829
+ r.startTime = Date.now(), r.harborContext = {}, e.success = function(n, s = 200) {
830
+ e.status(s).json({
831
+ success: !0,
832
+ data: n
833
+ });
834
+ }, e.error = function(n, s = 500, o) {
835
+ e.status(s).json({
836
+ success: !1,
837
+ error: {
838
+ message: n,
839
+ details: o
840
+ }
841
+ });
842
+ }, t();
843
+ };
844
+ }
845
+ function Re(r) {
846
+ ["SIGTERM", "SIGINT"].forEach((t) => {
847
+ process.on(t, async () => {
848
+ S.info(`Received ${t}, shutting down gracefully`), await r.stop(), process.exit(0);
849
+ });
850
+ });
851
+ }
852
+ class Z {
853
+ constructor(e, t) {
854
+ c(this, "_definition");
855
+ c(this, "_options");
856
+ c(this, "_paths", /* @__PURE__ */ new Map());
857
+ c(this, "_virtuals", /* @__PURE__ */ new Map());
858
+ c(this, "_methods", /* @__PURE__ */ new Map());
859
+ c(this, "_statics", /* @__PURE__ */ new Map());
860
+ c(this, "_preHooks", /* @__PURE__ */ new Map());
861
+ c(this, "_postHooks", /* @__PURE__ */ new Map());
862
+ c(this, "_indexes", []);
863
+ c(this, "_plugins", []);
864
+ // Public accessors for methods and statics
865
+ c(this, "methods", {});
866
+ c(this, "statics", {});
867
+ c(this, "virtuals", {});
868
+ if (this._definition = e, this._options = {
869
+ timestamps: !1,
870
+ strict: !0,
871
+ strictQuery: !1,
872
+ _id: !0,
873
+ id: !0,
874
+ versionKey: "__v",
875
+ autoIndex: !0,
876
+ autoCreate: !0,
877
+ minimize: !0,
878
+ ...t
879
+ }, this._parseDefinition(e), this._options._id && this._paths.set("_id", { type: "ObjectId", required: !1 }), this._options.timestamps) {
880
+ const n = typeof this._options.timestamps == "object" ? this._options.timestamps.createdAt === !1 ? null : this._options.timestamps.createdAt || "createdAt" : "createdAt", s = typeof this._options.timestamps == "object" ? this._options.timestamps.updatedAt === !1 ? null : this._options.timestamps.updatedAt || "updatedAt" : "updatedAt";
881
+ n && this._paths.set(n, { type: "Date", required: !1 }), s && this._paths.set(s, { type: "Date", required: !1 });
882
+ }
883
+ if (this._options.versionKey) {
884
+ const n = typeof this._options.versionKey == "string" ? this._options.versionKey : "__v";
885
+ this._paths.set(n, { type: "Number", default: 0 });
886
+ }
887
+ this.methods = new Proxy({}, {
888
+ set: (n, s, o) => (this._methods.set(s, o), !0),
889
+ get: (n, s) => this._methods.get(s)
890
+ }), this.statics = new Proxy({}, {
891
+ set: (n, s, o) => (this._statics.set(s, o), !0),
892
+ get: (n, s) => this._statics.get(s)
893
+ });
894
+ }
895
+ _parseDefinition(e, t = "") {
896
+ for (const [n, s] of Object.entries(e)) {
897
+ const o = t ? `${t}.${n}` : n;
898
+ if (typeof s == "string")
899
+ this._paths.set(o, { type: s });
900
+ else if (typeof s == "object" && s !== null) {
901
+ const i = s;
902
+ "type" in i ? typeof i.type == "string" ? this._paths.set(o, i) : Array.isArray(i.type) ? this._paths.set(o, { ...i, type: "Array" }) : typeof i.type == "object" && (this._paths.set(o, { type: "Object" }), this._parseDefinition(i.type, o)) : (this._paths.set(o, { type: "Object" }), this._parseDefinition(s, o));
903
+ }
904
+ }
905
+ }
906
+ // Add additional fields to schema
907
+ add(e, t) {
908
+ return this._parseDefinition(e, t), this;
909
+ }
910
+ // Get path definition
911
+ path(e) {
912
+ return this._paths.get(e);
913
+ }
914
+ // Get all paths
915
+ paths() {
916
+ return this._paths;
917
+ }
918
+ // Define virtual field
919
+ virtual(e) {
920
+ return new He(this, e);
921
+ }
922
+ // Define instance method
923
+ method(e, t) {
924
+ return this._methods.set(e, t), this;
925
+ }
926
+ // Define static method
927
+ static(e, t) {
928
+ return this._statics.set(e, t), this;
929
+ }
930
+ // Pre hook
931
+ pre(e, t) {
932
+ const n = Array.isArray(e) ? e : [e];
933
+ for (const s of n) {
934
+ const o = this._preHooks.get(s) || [];
935
+ o.push(t), this._preHooks.set(s, o);
936
+ }
937
+ return this;
938
+ }
939
+ // Post hook
940
+ post(e, t) {
941
+ const n = Array.isArray(e) ? e : [e];
942
+ for (const s of n) {
943
+ const o = this._postHooks.get(s) || [];
944
+ o.push(t), this._postHooks.set(s, o);
945
+ }
946
+ return this;
947
+ }
948
+ // Define index
949
+ index(e, t) {
950
+ return this._indexes.push({ fields: e, options: t }), this;
951
+ }
952
+ // Plugin support
953
+ plugin(e, t) {
954
+ return this._plugins.push({ fn: e, options: t }), e(this, t), this;
955
+ }
956
+ // Load class methods as schema methods
957
+ loadClass(e) {
958
+ const t = e.prototype;
959
+ for (const n of Object.getOwnPropertyNames(t)) {
960
+ if (n === "constructor") continue;
961
+ const s = Object.getOwnPropertyDescriptor(t, n);
962
+ if (s != null && s.get)
963
+ this._virtuals.set(n, { get: s.get });
964
+ else if (s != null && s.set) {
965
+ const o = this._virtuals.get(n) || {};
966
+ this._virtuals.set(n, { ...o, set: s.set });
967
+ } else typeof (s == null ? void 0 : s.value) == "function" && this._methods.set(n, s.value);
968
+ }
969
+ for (const n of Object.getOwnPropertyNames(e)) {
970
+ if (["length", "prototype", "name"].includes(n)) continue;
971
+ const s = e[n];
972
+ typeof s == "function" && this._statics.set(n, s);
973
+ }
974
+ return this;
975
+ }
976
+ // Clone schema
977
+ clone() {
978
+ const e = new Z({}, this._options);
979
+ return e._paths = new Map(this._paths), e._virtuals = new Map(this._virtuals), e._methods = new Map(this._methods), e._statics = new Map(this._statics), e._preHooks = new Map(this._preHooks), e._postHooks = new Map(this._postHooks), e._indexes = [...this._indexes], e;
980
+ }
981
+ // Getters
982
+ get options() {
983
+ return this._options;
984
+ }
985
+ get definition() {
986
+ return this._definition;
987
+ }
988
+ getMethods() {
989
+ return this._methods;
990
+ }
991
+ getStatics() {
992
+ return this._statics;
993
+ }
994
+ getVirtuals() {
995
+ return this._virtuals;
996
+ }
997
+ getPreHooks() {
998
+ return this._preHooks;
999
+ }
1000
+ getPostHooks() {
1001
+ return this._postHooks;
1002
+ }
1003
+ getIndexes() {
1004
+ return this._indexes;
1005
+ }
1006
+ // Validate document against schema
1007
+ async validate(e) {
1008
+ const t = [];
1009
+ for (const [n, s] of this._paths) {
1010
+ const o = this._getNestedValue(e, n), i = await this._validateField(n, o, s);
1011
+ t.push(...i);
1012
+ }
1013
+ return t.length > 0 ? { valid: !1, errors: t } : { valid: !0 };
1014
+ }
1015
+ _getNestedValue(e, t) {
1016
+ return t.split(".").reduce((n, s) => n == null ? void 0 : n[s], e);
1017
+ }
1018
+ async _validateField(e, t, n) {
1019
+ const s = [];
1020
+ return n.required && t == null ? (s.push({ path: e, message: `${e} is required` }), s) : t == null ? s : this._validateType(t, n.type) ? (n.type === "String" && typeof t == "string" && (n.minLength && t.length < n.minLength && s.push({ path: e, message: `${e} must be at least ${n.minLength} characters` }), n.maxLength && t.length > n.maxLength && s.push({ path: e, message: `${e} must be at most ${n.maxLength} characters` }), n.match && !n.match.test(t) && s.push({ path: e, message: `${e} does not match required pattern` }), n.enum && !n.enum.includes(t) && s.push({ path: e, message: `${e} must be one of: ${n.enum.join(", ")}` })), n.type === "Number" && typeof t == "number" && (n.min !== void 0 && t < n.min && s.push({ path: e, message: `${e} must be at least ${n.min}` }), n.max !== void 0 && t > n.max && s.push({ path: e, message: `${e} must be at most ${n.max}` })), n.validate && (await n.validate.validator(t) || s.push({ path: e, message: n.validate.message || `${e} failed validation` })), s) : (s.push({ path: e, message: `${e} must be of type ${n.type}` }), s);
1021
+ }
1022
+ _validateType(e, t) {
1023
+ switch (t) {
1024
+ case "String":
1025
+ return typeof e == "string";
1026
+ case "Number":
1027
+ return typeof e == "number" && !isNaN(e);
1028
+ case "Boolean":
1029
+ return typeof e == "boolean";
1030
+ case "Date":
1031
+ return e instanceof Date || typeof e == "string" && !isNaN(Date.parse(e));
1032
+ case "ObjectId":
1033
+ return typeof e == "string" && /^[0-9a-fA-F]{24}$/.test(e);
1034
+ case "Array":
1035
+ return Array.isArray(e);
1036
+ case "Object":
1037
+ case "Mixed":
1038
+ return typeof e == "object" && e !== null;
1039
+ case "Buffer":
1040
+ return Buffer.isBuffer(e);
1041
+ default:
1042
+ return !0;
1043
+ }
1044
+ }
1045
+ // Apply transformations (lowercase, uppercase, trim)
1046
+ transformValue(e, t) {
1047
+ const n = this._paths.get(e);
1048
+ if (!n || typeof t != "string") return t;
1049
+ let s = t;
1050
+ return n.lowercase && (s = s.toLowerCase()), n.uppercase && (s = s.toUpperCase()), n.trim && (s = s.trim()), s;
1051
+ }
1052
+ // Get default value for a field
1053
+ getDefault(e) {
1054
+ const t = this._paths.get(e);
1055
+ if (!(!t || t.default === void 0))
1056
+ return typeof t.default == "function" ? t.default() : t.default;
1057
+ }
1058
+ }
1059
+ class He {
1060
+ constructor(e, t) {
1061
+ c(this, "schema");
1062
+ c(this, "name");
1063
+ this.schema = e, this.name = t;
1064
+ }
1065
+ get(e) {
1066
+ const t = this.schema.getVirtuals(), n = t.get(this.name) || {};
1067
+ return t.set(this.name, { ...n, get: e }), this;
1068
+ }
1069
+ set(e) {
1070
+ const t = this.schema.getVirtuals(), n = t.get(this.name) || {};
1071
+ return t.set(this.name, { ...n, set: e }), this;
1072
+ }
1073
+ }
1074
+ class Ne extends oe {
1075
+ constructor() {
1076
+ super(...arguments);
1077
+ c(this, "_state", {
1078
+ connected: !1,
1079
+ readyState: 0
1080
+ });
1081
+ c(this, "_options", {});
1082
+ c(this, "_connectionUri", "");
1083
+ c(this, "_mongoClient", null);
1084
+ c(this, "_db", null);
1085
+ c(this, "_models", /* @__PURE__ */ new Map());
1086
+ }
1087
+ get readyState() {
1088
+ return this._state.readyState;
1089
+ }
1090
+ get host() {
1091
+ return this._state.host;
1092
+ }
1093
+ get port() {
1094
+ return this._state.port;
1095
+ }
1096
+ get name() {
1097
+ return this._state.name;
1098
+ }
1099
+ get db() {
1100
+ return this._db;
1101
+ }
1102
+ get client() {
1103
+ return this._mongoClient;
1104
+ }
1105
+ get models() {
1106
+ return this._models;
1107
+ }
1108
+ get uri() {
1109
+ return this._connectionUri;
1110
+ }
1111
+ async connect(t, n) {
1112
+ if (this._state.readyState === 1)
1113
+ return console.warn("[Harbor] Already connected to MongoDB"), this;
1114
+ this._connectionUri = t, this._options = {
1115
+ maxPoolSize: 10,
1116
+ minPoolSize: 1,
1117
+ serverSelectionTimeoutMS: 3e4,
1118
+ socketTimeoutMS: 45e3,
1119
+ retryWrites: !0,
1120
+ w: "majority",
1121
+ ...n
1122
+ }, this._state.readyState = 2, this.emit("connecting");
1123
+ try {
1124
+ const { MongoClient: s } = await import("mongodb");
1125
+ this._mongoClient = new s(t, this._options), await this._mongoClient.connect();
1126
+ const o = new URL(t), i = o.pathname.slice(1) || "test";
1127
+ return this._db = this._mongoClient.db(i), this._state = {
1128
+ connected: !0,
1129
+ readyState: 1,
1130
+ host: o.hostname,
1131
+ port: parseInt(o.port) || 27017,
1132
+ name: i
1133
+ }, this.emit("connected"), this.emit("open"), console.log(`[Harbor] ${C("database.connected", { uri: `${o.hostname}:${o.port}/${i}` })}`), this;
1134
+ } catch (s) {
1135
+ throw this._state.readyState = 0, this.emit("error", s), s;
1136
+ }
1137
+ }
1138
+ async disconnect() {
1139
+ if (this._state.readyState === 0) {
1140
+ console.warn("[Harbor] Already disconnected from MongoDB");
1141
+ return;
1142
+ }
1143
+ this._state.readyState = 3, this.emit("disconnecting");
1144
+ try {
1145
+ this._mongoClient && await this._mongoClient.close(), this._state = {
1146
+ connected: !1,
1147
+ readyState: 0
1148
+ }, this._mongoClient = null, this._db = null, this.emit("disconnected"), this.emit("close"), console.log(`[Harbor] ${C("database.disconnected")}`);
1149
+ } catch (t) {
1150
+ throw this.emit("error", t), t;
1151
+ }
1152
+ }
1153
+ async close() {
1154
+ return this.disconnect();
1155
+ }
1156
+ async ping() {
1157
+ if (!this._db)
1158
+ return !1;
1159
+ try {
1160
+ return await this._db.command({ ping: 1 }), !0;
1161
+ } catch {
1162
+ return !1;
1163
+ }
1164
+ }
1165
+ collection(t) {
1166
+ if (!this._db)
1167
+ throw new Error("[Harbor] Not connected to database");
1168
+ return this._db.collection(t);
1169
+ }
1170
+ async createCollection(t, n) {
1171
+ if (!this._db)
1172
+ throw new Error("[Harbor] Not connected to database");
1173
+ return this._db.createCollection(t, n);
1174
+ }
1175
+ async dropCollection(t) {
1176
+ if (!this._db)
1177
+ throw new Error("[Harbor] Not connected to database");
1178
+ return this._db.dropCollection(t);
1179
+ }
1180
+ async listCollections() {
1181
+ if (!this._db)
1182
+ throw new Error("[Harbor] Not connected to database");
1183
+ return (await this._db.listCollections().toArray()).map((n) => n.name);
1184
+ }
1185
+ async dropDatabase() {
1186
+ if (!this._db)
1187
+ throw new Error("[Harbor] Not connected to database");
1188
+ return this._db.dropDatabase();
1189
+ }
1190
+ // Transaction support
1191
+ async startSession() {
1192
+ if (!this._mongoClient)
1193
+ throw new Error("[Harbor] Not connected to database");
1194
+ return this._mongoClient.startSession();
1195
+ }
1196
+ async withTransaction(t, n) {
1197
+ const s = await this.startSession();
1198
+ try {
1199
+ let o;
1200
+ return await s.withTransaction(async () => {
1201
+ o = await t(s);
1202
+ }, n), o;
1203
+ } finally {
1204
+ await s.endSession();
1205
+ }
1206
+ }
1207
+ // Event handlers with proper typing
1208
+ on(t, n) {
1209
+ return super.on(t, n);
1210
+ }
1211
+ once(t, n) {
1212
+ return super.once(t, n);
1213
+ }
1214
+ }
1215
+ const j = new Ne();
1216
+ async function mt(r, e) {
1217
+ return j.connect(r, e);
1218
+ }
1219
+ async function ft() {
1220
+ return j.disconnect();
1221
+ }
1222
+ var Y;
1223
+ Y = Symbol.toStringTag;
1224
+ class H {
1225
+ constructor(e, t, n, s) {
1226
+ c(this, "_model");
1227
+ c(this, "_operation");
1228
+ c(this, "_filter", {});
1229
+ c(this, "_projection", null);
1230
+ c(this, "_options", {});
1231
+ c(this, "_update", null);
1232
+ c(this, "_currentPath", null);
1233
+ c(this, Y, "Query");
1234
+ this._model = e, this._operation = t, this._filter = n || {}, this._update = s || null;
1235
+ }
1236
+ select(e) {
1237
+ if (typeof e == "string") {
1238
+ this._projection = {};
1239
+ for (const t of e.split(" "))
1240
+ t.startsWith("-") ? this._projection[t.slice(1)] = 0 : t && (this._projection[t] = 1);
1241
+ } else
1242
+ this._projection = e;
1243
+ return this;
1244
+ }
1245
+ sort(e) {
1246
+ if (typeof e == "string") {
1247
+ const t = {};
1248
+ for (const n of e.split(" "))
1249
+ n.startsWith("-") ? t[n.slice(1)] = -1 : n && (t[n] = 1);
1250
+ this._options.sort = t;
1251
+ } else
1252
+ this._options.sort = e;
1253
+ return this;
1254
+ }
1255
+ limit(e) {
1256
+ return this._options.limit = e, this;
1257
+ }
1258
+ skip(e) {
1259
+ return this._options.skip = e, this;
1260
+ }
1261
+ lean() {
1262
+ return this._options.lean = !0, this;
1263
+ }
1264
+ populate(e) {
1265
+ return this._options.populate = e, this;
1266
+ }
1267
+ where(e, t) {
1268
+ return this._currentPath = e, t !== void 0 && (this._filter[e] = t), this;
1269
+ }
1270
+ equals(e) {
1271
+ return this._currentPath && (this._filter[this._currentPath] = e), this;
1272
+ }
1273
+ gt(e) {
1274
+ return this._currentPath && (this._filter[this._currentPath] = { ...this._filter[this._currentPath], $gt: e }), this;
1275
+ }
1276
+ gte(e) {
1277
+ return this._currentPath && (this._filter[this._currentPath] = { ...this._filter[this._currentPath], $gte: e }), this;
1278
+ }
1279
+ lt(e) {
1280
+ return this._currentPath && (this._filter[this._currentPath] = { ...this._filter[this._currentPath], $lt: e }), this;
1281
+ }
1282
+ lte(e) {
1283
+ return this._currentPath && (this._filter[this._currentPath] = { ...this._filter[this._currentPath], $lte: e }), this;
1284
+ }
1285
+ in(e) {
1286
+ return this._currentPath && (this._filter[this._currentPath] = { $in: e }), this;
1287
+ }
1288
+ nin(e) {
1289
+ return this._currentPath && (this._filter[this._currentPath] = { $nin: e }), this;
1290
+ }
1291
+ ne(e) {
1292
+ return this._currentPath && (this._filter[this._currentPath] = { $ne: e }), this;
1293
+ }
1294
+ regex(e) {
1295
+ return this._currentPath && (this._filter[this._currentPath] = { $regex: e }), this;
1296
+ }
1297
+ exists(e = !0) {
1298
+ return this._currentPath && (this._filter[this._currentPath] = { $exists: e }), this;
1299
+ }
1300
+ or(e) {
1301
+ return this._filter.$or = e, this;
1302
+ }
1303
+ and(e) {
1304
+ return this._filter.$and = e, this;
1305
+ }
1306
+ nor(e) {
1307
+ return this._filter.$nor = e, this;
1308
+ }
1309
+ async exec() {
1310
+ const e = this._model.getCollection();
1311
+ switch (this._operation) {
1312
+ case "find": {
1313
+ let t = e.find(this._filter, { projection: this._projection });
1314
+ this._options.sort && (t = t.sort(this._options.sort)), this._options.skip && (t = t.skip(this._options.skip)), this._options.limit && (t = t.limit(this._options.limit));
1315
+ const n = await t.toArray();
1316
+ return this._options.lean ? n : n.map((s) => this._model.hydrate(s));
1317
+ }
1318
+ case "findOne": {
1319
+ const t = await e.findOne(this._filter, { projection: this._projection });
1320
+ return t ? this._options.lean ? t : this._model.hydrate(t) : null;
1321
+ }
1322
+ case "findOneAndUpdate": {
1323
+ const t = await e.findOneAndUpdate(
1324
+ this._filter,
1325
+ this._update,
1326
+ {
1327
+ returnDocument: this._options.new ? "after" : "before",
1328
+ upsert: this._options.upsert,
1329
+ projection: this._projection
1330
+ }
1331
+ );
1332
+ return t ? this._options.lean ? t : this._model.hydrate(t) : null;
1333
+ }
1334
+ case "findOneAndDelete": {
1335
+ const t = await e.findOneAndDelete(this._filter, {
1336
+ projection: this._projection
1337
+ });
1338
+ return t ? this._options.lean ? t : this._model.hydrate(t) : null;
1339
+ }
1340
+ default:
1341
+ throw new Error(`Unknown operation: ${this._operation}`);
1342
+ }
1343
+ }
1344
+ then(e, t) {
1345
+ return this.exec().then(e, t);
1346
+ }
1347
+ catch(e) {
1348
+ return this.exec().catch(e);
1349
+ }
1350
+ finally(e) {
1351
+ return this.exec().finally(e);
1352
+ }
1353
+ }
1354
+ class Q {
1355
+ constructor(e, t) {
1356
+ c(this, "_id");
1357
+ c(this, "__v");
1358
+ c(this, "isNew", !0);
1359
+ c(this, "_model");
1360
+ c(this, "_modified", /* @__PURE__ */ new Set());
1361
+ /** Snapshot of document at load time for change tracking */
1362
+ c(this, "_original", {});
1363
+ var s;
1364
+ if (this._model = e, this._id = ((s = t == null ? void 0 : t._id) == null ? void 0 : s.toString()) || new v().toString(), t) {
1365
+ for (const [o, i] of Object.entries(t))
1366
+ o === "_id" ? this._id = (i == null ? void 0 : i.toString()) || this._id : this[o] = i;
1367
+ this._original = { ...t }, this.isNew = !1;
1368
+ }
1369
+ const n = e.schema;
1370
+ for (const [o] of n.paths())
1371
+ if (this[o] === void 0) {
1372
+ const i = n.getDefault(o);
1373
+ i !== void 0 && (this[o] = i);
1374
+ }
1375
+ for (const [o, i] of n.getVirtuals())
1376
+ Object.defineProperty(this, o, {
1377
+ get: i.get,
1378
+ set: i.set,
1379
+ enumerable: !0
1380
+ });
1381
+ for (const [o, i] of n.getMethods())
1382
+ this[o] = i.bind(this);
1383
+ }
1384
+ /** Snapshot of document at load for change tracking */
1385
+ get original() {
1386
+ return this._original;
1387
+ }
1388
+ get id() {
1389
+ return this._id;
1390
+ }
1391
+ isModified(e) {
1392
+ return e ? this._modified.has(e) : this._modified.size > 0;
1393
+ }
1394
+ markModified(e) {
1395
+ this._modified.add(e);
1396
+ }
1397
+ async save() {
1398
+ var i;
1399
+ const e = this._model.schema;
1400
+ await this._model.runPreHooks("save", this);
1401
+ const t = await e.validate(this.toObject());
1402
+ if (!t.valid) {
1403
+ const a = new Error(`Validation failed: ${(i = t.errors) == null ? void 0 : i.map((h) => h.message).join(", ")}`);
1404
+ throw a.errors = t.errors, a;
1405
+ }
1406
+ const n = /* @__PURE__ */ new Date();
1407
+ if (e.options.timestamps) {
1408
+ const a = typeof e.options.timestamps == "object" && e.options.timestamps.createdAt || "createdAt", h = typeof e.options.timestamps == "object" && e.options.timestamps.updatedAt || "updatedAt";
1409
+ this.isNew && a && (this[a] = n), this[h] = n;
1410
+ }
1411
+ const s = this._model.getCollection(), o = this.toObject();
1412
+ if (this.isNew)
1413
+ await s.insertOne({ _id: new v(this._id), ...o }), this.isNew = !1;
1414
+ else {
1415
+ if (e.options.versionKey) {
1416
+ const a = typeof e.options.versionKey == "string" ? e.options.versionKey : "__v";
1417
+ this[a] = (this[a] || 0) + 1;
1418
+ }
1419
+ await s.replaceOne({ _id: new v(this._id) }, o);
1420
+ }
1421
+ return this._original = { ...o }, this._modified.clear(), await this._model.runPostHooks("save", this), this;
1422
+ }
1423
+ async remove() {
1424
+ return await this._model.runPreHooks("remove", this), await this._model.getCollection().deleteOne({ _id: new v(this._id) }), await this._model.runPostHooks("remove", this), this;
1425
+ }
1426
+ async deleteOne() {
1427
+ await this._model.runPreHooks("deleteOne", this);
1428
+ const t = await this._model.getCollection().deleteOne({ _id: new v(this._id) });
1429
+ return await this._model.runPostHooks("deleteOne", this), {
1430
+ acknowledged: t.acknowledged,
1431
+ deletedCount: t.deletedCount
1432
+ };
1433
+ }
1434
+ async updateOne(e) {
1435
+ await this._model.runPreHooks("updateOne", this);
1436
+ const n = await this._model.getCollection().updateOne({ _id: new v(this._id) }, e);
1437
+ return await this._model.runPostHooks("updateOne", this), {
1438
+ acknowledged: n.acknowledged,
1439
+ modifiedCount: n.modifiedCount,
1440
+ matchedCount: n.matchedCount
1441
+ };
1442
+ }
1443
+ async populate(e) {
1444
+ return this;
1445
+ }
1446
+ toObject() {
1447
+ const e = { _id: this._id }, t = this._model.schema;
1448
+ for (const [n] of t.paths())
1449
+ n !== "_id" && this[n] !== void 0 && (e[n] = this[n]);
1450
+ return e;
1451
+ }
1452
+ toJSON() {
1453
+ return this.toObject();
1454
+ }
1455
+ }
1456
+ const U = class U {
1457
+ constructor(e, t, n) {
1458
+ c(this, "_name");
1459
+ c(this, "_schema");
1460
+ c(this, "_collectionName");
1461
+ this._name = e, this._schema = t, this._collectionName = n || e.toLowerCase() + "s";
1462
+ for (const [s, o] of t.getStatics())
1463
+ this[s] = o.bind(this);
1464
+ U.models.set(e, this);
1465
+ }
1466
+ get modelName() {
1467
+ return this._name;
1468
+ }
1469
+ get schema() {
1470
+ return this._schema;
1471
+ }
1472
+ get collection() {
1473
+ return { name: this._collectionName };
1474
+ }
1475
+ getCollection() {
1476
+ if (!j.db)
1477
+ throw new Error("[Harbor] Not connected to database. Call harbor.connect() first.");
1478
+ return j.db.collection(this._collectionName);
1479
+ }
1480
+ // Create a new document instance
1481
+ new(e) {
1482
+ return new Q(this, e);
1483
+ }
1484
+ // Hydrate a plain object into a document
1485
+ hydrate(e) {
1486
+ const t = new Q(this, e);
1487
+ return t.isNew = !1, t;
1488
+ }
1489
+ // Query methods
1490
+ find(e, t, n) {
1491
+ const s = new H(this, "find", e);
1492
+ return t && s.select(t), n != null && n.sort && s.sort(n.sort), n != null && n.limit && s.limit(n.limit), n != null && n.skip && s.skip(n.skip), n != null && n.lean && s.lean(), s;
1493
+ }
1494
+ findOne(e, t, n) {
1495
+ const s = new H(this, "findOne", e);
1496
+ return t && s.select(t), n != null && n.lean && s.lean(), s;
1497
+ }
1498
+ findById(e, t, n) {
1499
+ return this.findOne({ _id: new v(e) }, t, n);
1500
+ }
1501
+ // Create methods
1502
+ async create(e) {
1503
+ if (Array.isArray(e)) {
1504
+ const n = [];
1505
+ for (const s of e) {
1506
+ const o = this.new(s);
1507
+ await o.save(), n.push(o);
1508
+ }
1509
+ return n;
1510
+ }
1511
+ const t = this.new(e);
1512
+ return await t.save(), t;
1513
+ }
1514
+ async insertMany(e, t) {
1515
+ const n = this.getCollection(), s = e.map((i) => ({ _id: new v(), ...i })), o = await n.insertMany(s, { ordered: (t == null ? void 0 : t.ordered) ?? !0 });
1516
+ return {
1517
+ insertedCount: o.insertedCount,
1518
+ insertedIds: Object.values(o.insertedIds).map((i) => i.toString())
1519
+ };
1520
+ }
1521
+ // Update methods
1522
+ async updateOne(e, t, n) {
1523
+ var a;
1524
+ await this.runPreHooks("updateOne", null);
1525
+ const s = this.getCollection(), o = t.$set || t.$unset || t.$inc ? t : { $set: t }, i = await s.updateOne(e, o, { upsert: n == null ? void 0 : n.upsert });
1526
+ return await this.runPostHooks("updateOne", null), {
1527
+ acknowledged: i.acknowledged,
1528
+ modifiedCount: i.modifiedCount,
1529
+ matchedCount: i.matchedCount,
1530
+ upsertedCount: i.upsertedCount,
1531
+ upsertedId: (a = i.upsertedId) == null ? void 0 : a.toString()
1532
+ };
1533
+ }
1534
+ async updateMany(e, t, n) {
1535
+ await this.runPreHooks("updateMany", null);
1536
+ const s = this.getCollection(), o = t.$set || t.$unset || t.$inc ? t : { $set: t }, i = await s.updateMany(e, o, { upsert: n == null ? void 0 : n.upsert });
1537
+ return await this.runPostHooks("updateMany", null), {
1538
+ acknowledged: i.acknowledged,
1539
+ modifiedCount: i.modifiedCount,
1540
+ matchedCount: i.matchedCount
1541
+ };
1542
+ }
1543
+ findOneAndUpdate(e, t, n) {
1544
+ const s = new H(this, "findOneAndUpdate", e, t);
1545
+ return n != null && n.new && (s._options.new = !0), n != null && n.upsert && (s._options.upsert = !0), n != null && n.lean && s.lean(), s;
1546
+ }
1547
+ findByIdAndUpdate(e, t, n) {
1548
+ return this.findOneAndUpdate({ _id: new v(e) }, t, n);
1549
+ }
1550
+ async replaceOne(e, t, n) {
1551
+ const o = await this.getCollection().replaceOne(e, t, { upsert: n == null ? void 0 : n.upsert });
1552
+ return {
1553
+ acknowledged: o.acknowledged,
1554
+ modifiedCount: o.modifiedCount,
1555
+ matchedCount: o.matchedCount
1556
+ };
1557
+ }
1558
+ // Delete methods
1559
+ async deleteOne(e) {
1560
+ await this.runPreHooks("deleteOne", null);
1561
+ const n = await this.getCollection().deleteOne(e);
1562
+ return await this.runPostHooks("deleteOne", null), {
1563
+ acknowledged: n.acknowledged,
1564
+ deletedCount: n.deletedCount
1565
+ };
1566
+ }
1567
+ async deleteMany(e) {
1568
+ await this.runPreHooks("deleteMany", null);
1569
+ const n = await this.getCollection().deleteMany(e);
1570
+ return await this.runPostHooks("deleteMany", null), {
1571
+ acknowledged: n.acknowledged,
1572
+ deletedCount: n.deletedCount
1573
+ };
1574
+ }
1575
+ findOneAndDelete(e, t) {
1576
+ const n = new H(this, "findOneAndDelete", e);
1577
+ return t != null && t.lean && n.lean(), n;
1578
+ }
1579
+ findByIdAndDelete(e, t) {
1580
+ return this.findOneAndDelete({ _id: new v(e) }, t);
1581
+ }
1582
+ // Count methods
1583
+ async countDocuments(e) {
1584
+ return this.getCollection().countDocuments(e || {});
1585
+ }
1586
+ async estimatedDocumentCount() {
1587
+ return this.getCollection().estimatedDocumentCount();
1588
+ }
1589
+ // Aggregate
1590
+ async aggregate(e, t) {
1591
+ return this.getCollection().aggregate(e, t).toArray();
1592
+ }
1593
+ // Distinct
1594
+ async distinct(e, t) {
1595
+ return this.getCollection().distinct(e, t || {});
1596
+ }
1597
+ // Exists
1598
+ async exists(e) {
1599
+ const t = await this.findOne(e).select({ _id: 1 }).lean();
1600
+ return t ? { _id: t._id.toString() } : null;
1601
+ }
1602
+ // Bulk operations
1603
+ async bulkWrite(e) {
1604
+ const n = await this.getCollection().bulkWrite(e);
1605
+ return {
1606
+ ok: n.ok,
1607
+ insertedCount: n.insertedCount,
1608
+ matchedCount: n.matchedCount,
1609
+ modifiedCount: n.modifiedCount,
1610
+ deletedCount: n.deletedCount,
1611
+ upsertedCount: n.upsertedCount,
1612
+ insertedIds: n.insertedIds || {},
1613
+ upsertedIds: n.upsertedIds || {}
1614
+ };
1615
+ }
1616
+ // Index methods
1617
+ async createIndex(e, t) {
1618
+ return this.getCollection().createIndex(e, t);
1619
+ }
1620
+ async createIndexes(e) {
1621
+ const t = this.getCollection(), n = e.map((s) => ({ key: s.fields, ...s.options }));
1622
+ return t.createIndexes(n);
1623
+ }
1624
+ async listIndexes() {
1625
+ return this.getCollection().listIndexes().toArray();
1626
+ }
1627
+ async dropIndex(e) {
1628
+ await this.getCollection().dropIndex(e);
1629
+ }
1630
+ // Populate
1631
+ async populate(e, t) {
1632
+ return e;
1633
+ }
1634
+ // Watch (change streams)
1635
+ watch(e, t) {
1636
+ return this.getCollection().watch(e, t);
1637
+ }
1638
+ // Hook execution
1639
+ async runPreHooks(e, t) {
1640
+ const n = this._schema.getPreHooks().get(e) || [];
1641
+ for (const s of n)
1642
+ await new Promise((o, i) => {
1643
+ try {
1644
+ const a = s.call(t, o);
1645
+ a instanceof Promise && a.then(o).catch(i);
1646
+ } catch (a) {
1647
+ i(a);
1648
+ }
1649
+ });
1650
+ }
1651
+ async runPostHooks(e, t) {
1652
+ const n = this._schema.getPostHooks().get(e) || [];
1653
+ for (const s of n)
1654
+ await new Promise((o, i) => {
1655
+ try {
1656
+ const a = s.call(t, o);
1657
+ a instanceof Promise && a.then(o).catch(i);
1658
+ } catch (a) {
1659
+ i(a);
1660
+ }
1661
+ });
1662
+ }
1663
+ };
1664
+ c(U, "models", /* @__PURE__ */ new Map());
1665
+ let L = U;
1666
+ function gt(r, e, t) {
1667
+ const n = L.models.get(r);
1668
+ return n || new L(r, e, t);
1669
+ }
1670
+ const pt = {
1671
+ ObjectId: v
1672
+ }, k = A("changelog"), Ie = {
1673
+ filePath: "./CHANGELOG.md",
1674
+ format: "markdown",
1675
+ includeUnreleased: !0
1676
+ };
1677
+ function xe(r = {}) {
1678
+ const e = { ...Ie, ...r }, t = [];
1679
+ let n = [];
1680
+ function s() {
1681
+ const d = R(process.cwd(), e.filePath);
1682
+ if (!I(d)) {
1683
+ k.info("No changelog file found, starting fresh");
1684
+ return;
1685
+ }
1686
+ try {
1687
+ const l = X(d, "utf-8");
1688
+ o(l), k.info("Changelog loaded", { entries: t.length });
1689
+ } catch (l) {
1690
+ k.error("Failed to load changelog", l);
1691
+ }
1692
+ }
1693
+ function o(d) {
1694
+ const l = /## \[(\d+\.\d+\.\d+(?:-[\w.]+)?)\](?: - (\d{4}-\d{2}-\d{2}))?/g, u = d.split(l);
1695
+ for (let f = 1; f < u.length; f += 3) {
1696
+ const m = u[f], T = u[f + 1], y = u[f + 2];
1697
+ if (m && y) {
1698
+ const $ = {
1699
+ version: m,
1700
+ date: T ? new Date(T) : /* @__PURE__ */ new Date(),
1701
+ changes: i(y)
1702
+ };
1703
+ t.push($);
1704
+ }
1705
+ }
1706
+ }
1707
+ function i(d) {
1708
+ const l = [], u = d.split(`
1709
+ `);
1710
+ let f = null;
1711
+ for (const m of u) {
1712
+ const T = m.match(/^### (Added|Changed|Deprecated|Removed|Fixed|Security)/i);
1713
+ if (T) {
1714
+ f = T[1].toLowerCase();
1715
+ continue;
1716
+ }
1717
+ const y = m.match(/^- (.+)/);
1718
+ y && f && l.push({
1719
+ type: f,
1720
+ description: y[1].trim()
1721
+ });
1722
+ }
1723
+ return l;
1724
+ }
1725
+ function a() {
1726
+ const d = R(process.cwd(), e.filePath), l = h();
1727
+ se(d, l, "utf-8"), k.info("Changelog saved", { path: d });
1728
+ }
1729
+ function h() {
1730
+ let d = `# Changelog
1731
+
1732
+ `;
1733
+ d += `All notable changes to this project will be documented in this file.
1734
+
1735
+ `, d += `The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1736
+ `, d += `and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1737
+
1738
+ `, e.includeUnreleased && n.length > 0 && (d += `## [Unreleased]
1739
+
1740
+ `, d += g(n), d += `
1741
+ `);
1742
+ for (const l of t) {
1743
+ const u = l.date.toISOString().split("T")[0];
1744
+ if (d += `## [${l.version}] - ${u}
1745
+
1746
+ `, d += g(l.changes), l.breaking && l.breaking.length > 0) {
1747
+ d += `### BREAKING CHANGES
1748
+
1749
+ `;
1750
+ for (const f of l.breaking)
1751
+ d += `- ${f.description}
1752
+ `;
1753
+ d += `
1754
+ `;
1755
+ }
1756
+ d += `
1757
+ `;
1758
+ }
1759
+ return d;
1760
+ }
1761
+ function g(d) {
1762
+ const l = w(d);
1763
+ let u = "";
1764
+ const f = ["added", "changed", "deprecated", "removed", "fixed", "security"];
1765
+ for (const m of f) {
1766
+ const T = l[m];
1767
+ if (T && T.length > 0) {
1768
+ u += `### ${b(m)}
1769
+
1770
+ `;
1771
+ for (const y of T) {
1772
+ let $ = `- ${y.description}`;
1773
+ y.scope && ($ = `- **${y.scope}:** ${y.description}`), y.issue && ($ += ` (#${y.issue})`), u += $ + `
1774
+ `;
1775
+ }
1776
+ u += `
1777
+ `;
1778
+ }
1779
+ }
1780
+ return u;
1781
+ }
1782
+ function w(d) {
1783
+ const l = {
1784
+ added: [],
1785
+ changed: [],
1786
+ deprecated: [],
1787
+ removed: [],
1788
+ fixed: [],
1789
+ security: []
1790
+ };
1791
+ for (const u of d)
1792
+ l[u.type].push(u);
1793
+ return l;
1794
+ }
1795
+ function b(d) {
1796
+ return d.charAt(0).toUpperCase() + d.slice(1);
1797
+ }
1798
+ return {
1799
+ load: s,
1800
+ save: a,
1801
+ addChange(d, l, u) {
1802
+ n.push({
1803
+ type: d,
1804
+ description: l,
1805
+ scope: u == null ? void 0 : u.scope,
1806
+ issue: u == null ? void 0 : u.issue
1807
+ });
1808
+ },
1809
+ release(d) {
1810
+ const l = {
1811
+ version: d,
1812
+ date: /* @__PURE__ */ new Date(),
1813
+ changes: [...n]
1814
+ };
1815
+ return t.unshift(l), n = [], a(), k.info(`Released version ${d}`), l;
1816
+ },
1817
+ getEntries() {
1818
+ return [...t];
1819
+ },
1820
+ getUnreleased() {
1821
+ return [...n];
1822
+ },
1823
+ getLatestVersion() {
1824
+ var d;
1825
+ return ((d = t[0]) == null ? void 0 : d.version) ?? null;
1826
+ },
1827
+ getReleaseNotes(d) {
1828
+ var f;
1829
+ const l = t.find((m) => m.version === d);
1830
+ if (!l) return null;
1831
+ const u = w(l.changes);
1832
+ return {
1833
+ version: l.version,
1834
+ date: l.date,
1835
+ added: u.added.map((m) => m.description),
1836
+ changed: u.changed.map((m) => m.description),
1837
+ deprecated: u.deprecated.map((m) => m.description),
1838
+ removed: u.removed.map((m) => m.description),
1839
+ fixed: u.fixed.map((m) => m.description),
1840
+ security: u.security.map((m) => m.description),
1841
+ breaking: ((f = l.breaking) == null ? void 0 : f.map((m) => m.description)) ?? []
1842
+ };
1843
+ }
1844
+ };
1845
+ }
1846
+ class _t {
1847
+ constructor(e) {
1848
+ c(this, "manager");
1849
+ c(this, "load", () => this.manager.load());
1850
+ c(this, "save", () => this.manager.save());
1851
+ c(this, "addChange", (...e) => this.manager.addChange(...e));
1852
+ c(this, "release", (e) => this.manager.release(e));
1853
+ c(this, "getEntries", () => this.manager.getEntries());
1854
+ c(this, "getUnreleased", () => this.manager.getUnreleased());
1855
+ c(this, "getLatestVersion", () => this.manager.getLatestVersion());
1856
+ c(this, "getReleaseNotes", (e) => this.manager.getReleaseNotes(e));
1857
+ this.manager = xe(e);
1858
+ }
1859
+ }
1860
+ class De {
1861
+ constructor(e = {}) {
1862
+ this.options = e;
1863
+ }
1864
+ get config() {
1865
+ return this.options;
1866
+ }
1867
+ generate() {
1868
+ console.log("[Harbor] Portal generation is coming soon.");
1869
+ }
1870
+ }
1871
+ function yt(r) {
1872
+ return new De(r);
1873
+ }
1874
+ function wt() {
1875
+ console.log("[Harbor] API documentation generation is coming soon.");
1876
+ }
1877
+ function W(r) {
1878
+ return typeof r == "object" && r !== null && !Array.isArray(r);
1879
+ }
1880
+ function Me(r, e) {
1881
+ const t = { ...r };
1882
+ for (const n in e)
1883
+ if (Object.prototype.hasOwnProperty.call(e, n)) {
1884
+ const s = e[n], o = r[n];
1885
+ W(s) && W(o) ? t[n] = Me(
1886
+ o,
1887
+ s
1888
+ ) : s !== void 0 && (t[n] = s);
1889
+ }
1890
+ return t;
1891
+ }
1892
+ function vt(r, e) {
1893
+ const t = {};
1894
+ for (const n of e)
1895
+ Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);
1896
+ return t;
1897
+ }
1898
+ function bt(r, e) {
1899
+ const t = { ...r };
1900
+ for (const n of e)
1901
+ delete t[n];
1902
+ return t;
1903
+ }
1904
+ function Ct(r = 16) {
1905
+ const e = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1906
+ let t = "";
1907
+ for (let n = 0; n < r; n++)
1908
+ t += e.charAt(Math.floor(Math.random() * e.length));
1909
+ return t;
1910
+ }
1911
+ function Tt(r, e = "ISO") {
1912
+ if (e === "ISO")
1913
+ return r.toISOString();
1914
+ const t = r.getFullYear(), n = String(r.getMonth() + 1).padStart(2, "0"), s = String(r.getDate()).padStart(2, "0"), o = String(r.getHours()).padStart(2, "0"), i = String(r.getMinutes()).padStart(2, "0"), a = String(r.getSeconds()).padStart(2, "0");
1915
+ switch (e) {
1916
+ case "DATE":
1917
+ return `${t}-${n}-${s}`;
1918
+ case "TIME":
1919
+ return `${o}:${i}:${a}`;
1920
+ case "DATETIME":
1921
+ return `${t}-${n}-${s} ${o}:${i}:${a}`;
1922
+ default:
1923
+ return r.toISOString();
1924
+ }
1925
+ }
1926
+ function Ot(r) {
1927
+ return new Promise((e) => setTimeout(e, r));
1928
+ }
1929
+ const N = A("http"), _ = {
1930
+ info: "\x1B[36m",
1931
+ // Cyan for 1xx
1932
+ success: "\x1B[32m",
1933
+ // Green for 2xx
1934
+ redirect: "\x1B[36m",
1935
+ // Cyan for 3xx
1936
+ clientError: "\x1B[33m",
1937
+ // Yellow for 4xx
1938
+ serverError: "\x1B[31m",
1939
+ // Red for 5xx
1940
+ reset: "\x1B[0m"
1941
+ };
1942
+ function je(r) {
1943
+ return r >= 500 ? _.serverError : r >= 400 ? _.clientError : r >= 300 ? _.redirect : r >= 200 ? _.success : _.info;
1944
+ }
1945
+ function G(r) {
1946
+ return {
1947
+ GET: "\x1B[32m",
1948
+ // Green
1949
+ POST: "\x1B[34m",
1950
+ // Blue
1951
+ PUT: "\x1B[33m",
1952
+ // Yellow
1953
+ PATCH: "\x1B[35m",
1954
+ // Magenta
1955
+ DELETE: "\x1B[31m",
1956
+ // Red
1957
+ OPTIONS: "\x1B[36m",
1958
+ // Cyan
1959
+ HEAD: "\x1B[36m"
1960
+ // Cyan
1961
+ }[r] ?? "\x1B[0m";
1962
+ }
1963
+ function Le(r) {
1964
+ return r === 0 ? "-" : r < 1024 ? `${r}B` : r < 1024 * 1024 ? `${(r / 1024).toFixed(1)}KB` : `${(r / (1024 * 1024)).toFixed(1)}MB`;
1965
+ }
1966
+ function Ue(r, e, t) {
1967
+ const n = Date.now() - t, s = e.statusCode, o = e.get("content-length") ?? "0";
1968
+ return {
1969
+ method: r.method,
1970
+ url: r.originalUrl || r.url,
1971
+ status: s,
1972
+ statusColor: je(s),
1973
+ responseTime: n,
1974
+ contentLength: Le(parseInt(o, 10) || 0),
1975
+ remoteAddr: r.ip || r.socket.remoteAddress || "-",
1976
+ date: (/* @__PURE__ */ new Date()).toISOString(),
1977
+ httpVersion: `HTTP/${r.httpVersionMajor}.${r.httpVersionMinor}`,
1978
+ userAgent: r.get("user-agent") ?? "-",
1979
+ referrer: r.get("referrer") ?? "-"
1980
+ };
1981
+ }
1982
+ const Fe = {
1983
+ tiny: (r, e) => {
1984
+ const t = e ? `${G(r.method)}${r.method}${_.reset}` : r.method, n = e ? `${r.statusColor}${r.status}${_.reset}` : String(r.status);
1985
+ return `${t} ${r.url} ${n} ${r.responseTime}ms`;
1986
+ },
1987
+ short: (r, e) => {
1988
+ const t = e ? `${G(r.method)}${r.method}${_.reset}` : r.method, n = e ? `${r.statusColor}${r.status}${_.reset}` : String(r.status);
1989
+ return `${r.remoteAddr} ${t} ${r.url} ${n} ${r.responseTime}ms - ${r.contentLength}`;
1990
+ },
1991
+ dev: (r, e) => {
1992
+ const t = e ? `${G(r.method)}${r.method.padEnd(7)}${_.reset}` : r.method.padEnd(7), n = e ? `${r.statusColor}${r.status}${_.reset}` : String(r.status), s = r.responseTime < 100 ? `${r.responseTime}ms` : r.responseTime < 1e3 ? `\x1B[33m${r.responseTime}ms${_.reset}` : `\x1B[31m${r.responseTime}ms${_.reset}`;
1993
+ return `${t} ${r.url} ${n} ${e ? s : `${r.responseTime}ms`} - ${r.contentLength}`;
1994
+ },
1995
+ combined: (r) => `${r.remoteAddr} - - [${r.date}] "${r.method} ${r.url} ${r.httpVersion}" ${r.status} ${r.contentLength} "${r.referrer}" "${r.userAgent}"`,
1996
+ common: (r) => `${r.remoteAddr} - - [${r.date}] "${r.method} ${r.url} ${r.httpVersion}" ${r.status} ${r.contentLength}`,
1997
+ custom: () => ""
1998
+ // Handled separately
1999
+ };
2000
+ function Et(r = {}) {
2001
+ const {
2002
+ format: e = "dev",
2003
+ skip: t,
2004
+ immediate: n = !1,
2005
+ customFormat: s,
2006
+ colorize: o = !0
2007
+ } = r;
2008
+ return (i, a, h) => {
2009
+ const g = Date.now();
2010
+ n && N.info(C("http.requestStart", { method: i.method, url: i.url }));
2011
+ const w = a.end;
2012
+ a.end = function(b, d, l) {
2013
+ a.end = w;
2014
+ const u = a.end(b, d, l);
2015
+ if (t && t(i, a))
2016
+ return u;
2017
+ const f = Ue(i, a, g);
2018
+ let m;
2019
+ return e === "custom" && s ? m = s(f) : m = Fe[e](f, o), f.status >= 500 ? N.error(m) : f.status >= 400 ? N.warn(m) : N.info(m), u;
2020
+ }, h();
2021
+ };
2022
+ }
2023
+ const St = {
2024
+ /** Skip successful responses */
2025
+ successOnly: (r, e) => e.statusCode < 400,
2026
+ /** Skip health check endpoints */
2027
+ healthChecks: (r) => r.url === "/health" || r.url === "/healthz" || r.url === "/ready",
2028
+ /** Skip static files */
2029
+ staticFiles: (r) => /\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/i.test(r.url),
2030
+ /** Skip based on custom paths */
2031
+ paths: (r) => (e) => r.some((t) => e.url.startsWith(t))
2032
+ };
2033
+ function At(r) {
2034
+ return r;
2035
+ }
2036
+ export {
2037
+ Je as CONTENT_TYPES,
2038
+ _t as ChangelogManager,
2039
+ lt as DELETE,
2040
+ jt as DockerManager,
2041
+ it as GET,
2042
+ Ze as HEADERS,
2043
+ Xe as HTTP_METHODS,
2044
+ p as HTTP_STATUS,
2045
+ Q as HarborDocument,
2046
+ O as HarborError,
2047
+ L as Model,
2048
+ Ht as MongoValidator,
2049
+ dt as PATCH,
2050
+ at as POST,
2051
+ ct as PUT,
2052
+ De as PortalGenerator,
2053
+ H as Query,
2054
+ J as RouteBuilder,
2055
+ Z as Schema,
2056
+ pt as Types,
2057
+ st as addTranslations,
2058
+ mt as connect,
2059
+ j as connection,
2060
+ xe as createChangelogManager,
2061
+ At as createCustomFormat,
2062
+ Lt as createDockerManager,
2063
+ Ee as createErrorHandler,
2064
+ A as createLogger,
2065
+ Nt as createMongoSchema,
2066
+ It as createParamValidator,
2067
+ yt as createPortal,
2068
+ K as createRouter,
2069
+ ht as createServer,
2070
+ Me as deepMerge,
2071
+ et as defineConfig,
2072
+ ft as disconnect,
2073
+ Tt as formatDate,
2074
+ wt as generateDocs,
2075
+ Ct as generateId,
2076
+ rt as getAvailableLocales,
2077
+ nt as getLocale,
2078
+ Et as httpLogger,
2079
+ me as loadConfig,
2080
+ gt as model,
2081
+ bt as omit,
2082
+ vt as pick,
2083
+ ot as registerLocale,
2084
+ ut as route,
2085
+ kt as setGlobalLogLevel,
2086
+ tt as setLocale,
2087
+ St as skipFunctions,
2088
+ Ot as sleep,
2089
+ C as t,
2090
+ xt as validateField,
2091
+ F as validateRequest,
2092
+ Dt as validators
2093
+ };
2094
+ //# sourceMappingURL=index.es.js.map