crudora 0.2.1 → 0.3.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.
package/dist/index.cjs CHANGED
@@ -1451,6 +1451,7 @@ var Crudora = class {
1451
1451
  };
1452
1452
 
1453
1453
  // src/core/crudoraServer.ts
1454
+ var import_http = __toESM(require("http"), 1);
1454
1455
  var import_express = __toESM(require("express"), 1);
1455
1456
  var import_crypto2 = require("crypto");
1456
1457
  function createRateLimiter(config) {
@@ -1497,6 +1498,7 @@ function createDefaultLogger() {
1497
1498
  }
1498
1499
  var CrudoraServer = class {
1499
1500
  constructor(config) {
1501
+ this.httpServer = null;
1500
1502
  const resolvedLogger = config.logger === void 0 ? createDefaultLogger() : config.logger;
1501
1503
  const resolvedRateLimit = config.rateLimit === false ? false : {
1502
1504
  windowMs: config.rateLimit?.windowMs ?? 6e4,
@@ -1510,6 +1512,8 @@ var CrudoraServer = class {
1510
1512
  bodyParser: true,
1511
1513
  bodyParserLimit: "100kb",
1512
1514
  basePath: "/api",
1515
+ timeout: 0,
1516
+ healthCheck: true,
1513
1517
  ...config,
1514
1518
  logger: resolvedLogger,
1515
1519
  rateLimit: resolvedRateLimit
@@ -1533,6 +1537,19 @@ var CrudoraServer = class {
1533
1537
  req.correlationId = (0, import_crypto2.randomUUID)();
1534
1538
  next();
1535
1539
  });
1540
+ if (this.config.timeout > 0) {
1541
+ const timeoutMs = this.config.timeout;
1542
+ this.app.use((_req, res, next) => {
1543
+ const timer = setTimeout(() => {
1544
+ if (!res.headersSent) {
1545
+ res.status(503).json({ success: false, error: { code: "TIMEOUT", message: "Request timed out" } });
1546
+ }
1547
+ }, timeoutMs);
1548
+ res.on("finish", () => clearTimeout(timer));
1549
+ res.on("close", () => clearTimeout(timer));
1550
+ next();
1551
+ });
1552
+ }
1536
1553
  if (this.config.rateLimit !== false) {
1537
1554
  this.app.use(createRateLimiter(this.config.rateLimit));
1538
1555
  }
@@ -1574,6 +1591,12 @@ var CrudoraServer = class {
1574
1591
  return this;
1575
1592
  }
1576
1593
  generateRoutes() {
1594
+ if (this.config.healthCheck !== false) {
1595
+ const healthPath = typeof this.config.healthCheck === "string" ? this.config.healthCheck : "/health";
1596
+ this.app.get(healthPath, (_req, res) => {
1597
+ res.json({ success: true, data: { status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() } });
1598
+ });
1599
+ }
1577
1600
  this.crudora.generateRoutes(this.app, this.config.basePath);
1578
1601
  return this;
1579
1602
  }
@@ -1581,12 +1604,29 @@ var CrudoraServer = class {
1581
1604
  this.app.use(middleware);
1582
1605
  return this;
1583
1606
  }
1607
+ /**
1608
+ * Starts the HTTP server and returns the underlying `http.Server` instance.
1609
+ * Use the returned server for graceful shutdown:
1610
+ *
1611
+ * @example
1612
+ * const httpServer = server.listen();
1613
+ * process.on('SIGTERM', () => httpServer.close(() => process.exit(0)));
1614
+ */
1584
1615
  listen(callback) {
1585
- this.app.listen(this.config.port, () => {
1616
+ this.httpServer = import_http.default.createServer(this.app);
1617
+ this.httpServer.listen(this.config.port, () => {
1586
1618
  console.log(`\u{1F680} Crudora server running on port ${this.config.port}`);
1587
1619
  console.log(`\u{1F4DA} API available at http://localhost:${this.config.port}${this.config.basePath}`);
1588
1620
  if (callback) callback();
1589
1621
  });
1622
+ return this.httpServer;
1623
+ }
1624
+ /**
1625
+ * Returns the `http.Server` instance after `listen()` has been called, or `null` before.
1626
+ * Useful when you need the server reference without calling listen again.
1627
+ */
1628
+ getHttpServer() {
1629
+ return this.httpServer;
1590
1630
  }
1591
1631
  getApp() {
1592
1632
  return this.app;