@spfn/core 0.1.0-alpha.64 → 0.1.0-alpha.68

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 (37) hide show
  1. package/README.md +5 -5
  2. package/dist/{auto-loader-CdsxOceW.d.ts → auto-loader-JFaZ9gON.d.ts} +3 -2
  3. package/dist/cache/index.d.ts +211 -0
  4. package/dist/cache/index.js +992 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/client/index.d.ts +2 -2
  7. package/dist/codegen/generators/index.d.ts +7 -6
  8. package/dist/codegen/generators/index.js +208 -27
  9. package/dist/codegen/generators/index.js.map +1 -1
  10. package/dist/codegen/index.d.ts +67 -118
  11. package/dist/codegen/index.js +1419 -1295
  12. package/dist/codegen/index.js.map +1 -1
  13. package/dist/database-errors-CoPrcOpq.d.ts +86 -0
  14. package/dist/db/index.d.ts +316 -9
  15. package/dist/db/index.js +6 -6
  16. package/dist/db/index.js.map +1 -1
  17. package/dist/error-handler-wjLL3v-a.d.ts +44 -0
  18. package/dist/errors/index.d.ts +119 -0
  19. package/dist/errors/index.js +160 -0
  20. package/dist/errors/index.js.map +1 -0
  21. package/dist/index-DHiAqhKv.d.ts +101 -0
  22. package/dist/index.d.ts +2 -228
  23. package/dist/index.js +274 -292
  24. package/dist/index.js.map +1 -1
  25. package/dist/middleware/index.d.ts +33 -0
  26. package/dist/middleware/index.js +890 -0
  27. package/dist/middleware/index.js.map +1 -0
  28. package/dist/route/index.d.ts +172 -7
  29. package/dist/route/index.js +209 -70
  30. package/dist/route/index.js.map +1 -1
  31. package/dist/server/index.js +267 -176
  32. package/dist/server/index.js.map +1 -1
  33. package/dist/{types-Bd8YsFSU.d.ts → types-CAON3Mmg.d.ts} +1 -1
  34. package/package.json +19 -2
  35. package/dist/bind-CSzshBtm.d.ts +0 -17
  36. package/dist/contract-generator-CqKsfsNE.d.ts +0 -52
  37. package/dist/postgres-errors-lw1aRUFe.d.ts +0 -397
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { join, dirname, relative, basename } from 'path';
4
4
  import { config } from 'dotenv';
5
5
  import postgres from 'postgres';
6
6
  import { drizzle } from 'drizzle-orm/postgres-js';
7
- import { bigserial, timestamp, pgSchema } from 'drizzle-orm/pg-core';
7
+ import { timestamp, bigserial, pgSchema } from 'drizzle-orm/pg-core';
8
8
  import { AsyncLocalStorage } from 'async_hooks';
9
9
  import { randomUUID, randomBytes } from 'crypto';
10
10
  import { createMiddleware } from 'hono/factory';
@@ -12,7 +12,6 @@ import { eq, and } from 'drizzle-orm';
12
12
  import { Hono } from 'hono';
13
13
  import { cors } from 'hono/cors';
14
14
  import { readdir, stat } from 'fs/promises';
15
- import { Value } from '@sinclair/typebox/value';
16
15
  import { serve } from '@hono/node-server';
17
16
  import { networkInterfaces } from 'os';
18
17
 
@@ -129,11 +128,11 @@ function formatTimestampHuman(date) {
129
128
  const ms = String(date.getMilliseconds()).padStart(3, "0");
130
129
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;
131
130
  }
132
- function formatError(error) {
131
+ function formatError(error2) {
133
132
  const lines = [];
134
- lines.push(`${error.name}: ${error.message}`);
135
- if (error.stack) {
136
- const stackLines = error.stack.split("\n").slice(1);
133
+ lines.push(`${error2.name}: ${error2.message}`);
134
+ if (error2.stack) {
135
+ const stackLines = error2.stack.split("\n").slice(1);
137
136
  lines.push(...stackLines);
138
137
  }
139
138
  return lines.join("\n");
@@ -319,7 +318,7 @@ var init_logger = __esm({
319
318
  /**
320
319
  * Log processing (internal)
321
320
  */
322
- log(level, message, error, context) {
321
+ log(level, message, error2, context) {
323
322
  if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.config.level]) {
324
323
  return;
325
324
  }
@@ -328,7 +327,7 @@ var init_logger = __esm({
328
327
  level,
329
328
  message,
330
329
  module: this.module,
331
- error,
330
+ error: error2,
332
331
  // Mask sensitive information in context to prevent credential leaks
333
332
  context: context ? maskSensitiveData(context) : void 0
334
333
  };
@@ -339,8 +338,8 @@ var init_logger = __esm({
339
338
  */
340
339
  processTransports(metadata) {
341
340
  const promises = this.config.transports.filter((transport) => transport.enabled).map((transport) => this.safeTransportLog(transport, metadata));
342
- Promise.all(promises).catch((error) => {
343
- const errorMessage = error instanceof Error ? error.message : String(error);
341
+ Promise.all(promises).catch((error2) => {
342
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
344
343
  process.stderr.write(`[Logger] Transport error: ${errorMessage}
345
344
  `);
346
345
  });
@@ -351,8 +350,8 @@ var init_logger = __esm({
351
350
  async safeTransportLog(transport, metadata) {
352
351
  try {
353
352
  await transport.log(metadata);
354
- } catch (error) {
355
- const errorMessage = error instanceof Error ? error.message : String(error);
353
+ } catch (error2) {
354
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
356
355
  process.stderr.write(`[Logger] Transport "${transport.name}" failed: ${errorMessage}
357
356
  `);
358
357
  }
@@ -442,11 +441,11 @@ var init_file = __esm({
442
441
  }
443
442
  if (this.currentStream) {
444
443
  return new Promise((resolve, reject) => {
445
- this.currentStream.write(message + "\n", "utf-8", (error) => {
446
- if (error) {
447
- process.stderr.write(`[FileTransport] Failed to write log: ${error.message}
444
+ this.currentStream.write(message + "\n", "utf-8", (error2) => {
445
+ if (error2) {
446
+ process.stderr.write(`[FileTransport] Failed to write log: ${error2.message}
448
447
  `);
449
- reject(error);
448
+ reject(error2);
450
449
  } else {
451
450
  resolve();
452
451
  }
@@ -468,8 +467,8 @@ var init_file = __esm({
468
467
  encoding: "utf-8"
469
468
  });
470
469
  this.currentFilename = filename;
471
- this.currentStream.on("error", (error) => {
472
- process.stderr.write(`[FileTransport] Stream error: ${error.message}
470
+ this.currentStream.on("error", (error2) => {
471
+ process.stderr.write(`[FileTransport] Stream error: ${error2.message}
473
472
  `);
474
473
  this.currentStream = null;
475
474
  this.currentFilename = null;
@@ -483,9 +482,9 @@ var init_file = __esm({
483
482
  return;
484
483
  }
485
484
  return new Promise((resolve, reject) => {
486
- this.currentStream.end((error) => {
487
- if (error) {
488
- reject(error);
485
+ this.currentStream.end((error2) => {
486
+ if (error2) {
487
+ reject(error2);
489
488
  } else {
490
489
  this.currentStream = null;
491
490
  this.currentFilename = null;
@@ -510,8 +509,8 @@ var init_file = __esm({
510
509
  if (stats.size >= this.maxFileSize) {
511
510
  await this.rotateBySize();
512
511
  }
513
- } catch (error) {
514
- const errorMessage = error instanceof Error ? error.message : String(error);
512
+ } catch (error2) {
513
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
515
514
  process.stderr.write(`[FileTransport] Failed to check file size: ${errorMessage}
516
515
  `);
517
516
  }
@@ -537,8 +536,8 @@ var init_file = __esm({
537
536
  const newPath2 = join(this.logDir, `${baseName}.${newNum}.log`);
538
537
  try {
539
538
  renameSync(oldPath, newPath2);
540
- } catch (error) {
541
- const errorMessage = error instanceof Error ? error.message : String(error);
539
+ } catch (error2) {
540
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
542
541
  process.stderr.write(`[FileTransport] Failed to rotate file: ${errorMessage}
543
542
  `);
544
543
  }
@@ -550,8 +549,8 @@ var init_file = __esm({
550
549
  if (existsSync(currentPath)) {
551
550
  renameSync(currentPath, newPath);
552
551
  }
553
- } catch (error) {
554
- const errorMessage = error instanceof Error ? error.message : String(error);
552
+ } catch (error2) {
553
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
555
554
  process.stderr.write(`[FileTransport] Failed to rotate current file: ${errorMessage}
556
555
  `);
557
556
  }
@@ -578,15 +577,15 @@ var init_file = __esm({
578
577
  const filepath = join(this.logDir, file);
579
578
  try {
580
579
  unlinkSync(filepath);
581
- } catch (error) {
582
- const errorMessage = error instanceof Error ? error.message : String(error);
580
+ } catch (error2) {
581
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
583
582
  process.stderr.write(`[FileTransport] Failed to delete old file "${file}": ${errorMessage}
584
583
  `);
585
584
  }
586
585
  }
587
586
  }
588
- } catch (error) {
589
- const errorMessage = error instanceof Error ? error.message : String(error);
587
+ } catch (error2) {
588
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
590
589
  process.stderr.write(`[FileTransport] Failed to clean old files: ${errorMessage}
591
590
  `);
592
591
  }
@@ -645,8 +644,8 @@ function validateDirectoryWritable(dirPath) {
645
644
  if (!existsSync(dirPath)) {
646
645
  try {
647
646
  mkdirSync(dirPath, { recursive: true });
648
- } catch (error) {
649
- const errorMessage = error instanceof Error ? error.message : String(error);
647
+ } catch (error2) {
648
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
650
649
  throw new Error(`Failed to create log directory "${dirPath}": ${errorMessage}`);
651
650
  }
652
651
  }
@@ -659,8 +658,8 @@ function validateDirectoryWritable(dirPath) {
659
658
  try {
660
659
  writeFileSync(testFile, "test", "utf-8");
661
660
  unlinkSync(testFile);
662
- } catch (error) {
663
- const errorMessage = error instanceof Error ? error.message : String(error);
661
+ } catch (error2) {
662
+ const errorMessage = error2 instanceof Error ? error2.message : String(error2);
664
663
  throw new Error(`Cannot write to log directory "${dirPath}": ${errorMessage}`);
665
664
  }
666
665
  }
@@ -737,11 +736,11 @@ function validateConfig() {
737
736
  validateFileConfig();
738
737
  validateSlackConfig();
739
738
  validateEmailConfig();
740
- } catch (error) {
741
- if (error instanceof Error) {
742
- throw new Error(`[Logger] Configuration validation failed: ${error.message}`);
739
+ } catch (error2) {
740
+ if (error2 instanceof Error) {
741
+ throw new Error(`[Logger] Configuration validation failed: ${error2.message}`);
743
742
  }
744
- throw error;
743
+ throw error2;
745
744
  }
746
745
  }
747
746
  var init_config = __esm({
@@ -879,24 +878,28 @@ function discoverFunctionRoutes(cwd = process.cwd()) {
879
878
  const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
880
879
  if (pkg.spfn?.routes?.dir) {
881
880
  const { dir } = pkg.spfn.routes;
881
+ const prefix = pkg.spfn.prefix;
882
882
  const packagePath = dirname(pkgPath);
883
883
  const routesDir = join(packagePath, dir);
884
884
  functions.push({
885
885
  packageName,
886
886
  routesDir,
887
- packagePath
887
+ packagePath,
888
+ prefix
889
+ // Include prefix in function info
888
890
  });
889
891
  routeLogger.debug("Discovered function routes", {
890
892
  package: packageName,
891
- dir
893
+ dir,
894
+ prefix: prefix || "(none)"
892
895
  });
893
896
  }
894
- } catch (error) {
897
+ } catch (error2) {
895
898
  }
896
899
  }
897
- } catch (error) {
900
+ } catch (error2) {
898
901
  routeLogger.warn("Failed to discover function routes", {
899
- error: error instanceof Error ? error.message : "Unknown error"
902
+ error: error2 instanceof Error ? error2.message : "Unknown error"
900
903
  });
901
904
  }
902
905
  return functions;
@@ -910,7 +913,7 @@ var init_function_routes = __esm({
910
913
  });
911
914
 
912
915
  // src/errors/database-errors.ts
913
- var DatabaseError, ConnectionError, QueryError, NotFoundError, ValidationError, TransactionError, DeadlockError, DuplicateEntryError;
916
+ var DatabaseError, ConnectionError, QueryError, ConstraintViolationError, TransactionError, DeadlockError, DuplicateEntryError;
914
917
  var init_database_errors = __esm({
915
918
  "src/errors/database-errors.ts"() {
916
919
  DatabaseError = class extends Error {
@@ -950,16 +953,10 @@ var init_database_errors = __esm({
950
953
  this.name = "QueryError";
951
954
  }
952
955
  };
953
- NotFoundError = class extends QueryError {
954
- constructor(resource, id2) {
955
- super(`${resource} with id ${id2} not found`, 404, { resource, id: id2 });
956
- this.name = "NotFoundError";
957
- }
958
- };
959
- ValidationError = class extends QueryError {
956
+ ConstraintViolationError = class extends QueryError {
960
957
  constructor(message, details) {
961
958
  super(message, 400, details);
962
- this.name = "ValidationError";
959
+ this.name = "ConstraintViolationError";
963
960
  }
964
961
  };
965
962
  TransactionError = class extends DatabaseError {
@@ -990,9 +987,6 @@ var init_http_errors = __esm({
990
987
  });
991
988
 
992
989
  // src/errors/error-utils.ts
993
- function isDatabaseError(error) {
994
- return error instanceof DatabaseError;
995
- }
996
990
  var init_error_utils = __esm({
997
991
  "src/errors/error-utils.ts"() {
998
992
  init_database_errors();
@@ -1082,8 +1076,8 @@ function loadSingleFile(filePath, debug) {
1082
1076
  });
1083
1077
  }
1084
1078
  return { success: true, parsed };
1085
- } catch (error) {
1086
- const message = error instanceof Error ? error.message : "Unknown error";
1079
+ } catch (error2) {
1080
+ const message = error2 instanceof Error ? error2.message : "Unknown error";
1087
1081
  envLogger.error("Error loading environment file", {
1088
1082
  path: filePath,
1089
1083
  error: message
@@ -1099,12 +1093,12 @@ function validateRequiredVars(required, debug) {
1099
1093
  }
1100
1094
  }
1101
1095
  if (missing.length > 0) {
1102
- const error = `Required environment variables missing: ${missing.join(", ")}`;
1096
+ const error2 = `Required environment variables missing: ${missing.join(", ")}`;
1103
1097
  envLogger.error("Environment validation failed", {
1104
1098
  missing,
1105
1099
  required
1106
1100
  });
1107
- throw new Error(error);
1101
+ throw new Error(error2);
1108
1102
  }
1109
1103
  if (debug) {
1110
1104
  envLogger.debug("Required environment variables validated", {
@@ -1185,12 +1179,12 @@ function loadEnvironment(options = {}) {
1185
1179
  if (required.length > 0) {
1186
1180
  try {
1187
1181
  validateRequiredVars(required, debug);
1188
- } catch (error) {
1182
+ } catch (error2) {
1189
1183
  result.success = false;
1190
1184
  result.errors = [
1191
- error instanceof Error ? error.message : "Validation failed"
1185
+ error2 instanceof Error ? error2.message : "Validation failed"
1192
1186
  ];
1193
- throw error;
1187
+ throw error2;
1194
1188
  }
1195
1189
  }
1196
1190
  if (result.warnings.length > 0) {
@@ -1247,9 +1241,9 @@ function parseUniqueViolation(message) {
1247
1241
  }
1248
1242
  return null;
1249
1243
  }
1250
- function fromPostgresError(error) {
1251
- const code = error?.code;
1252
- const message = error?.message || "Database error occurred";
1244
+ function fromPostgresError(error2) {
1245
+ const code = error2?.code;
1246
+ const message = error2?.message || "Database error occurred";
1253
1247
  switch (code) {
1254
1248
  // Class 08 — Connection Exception
1255
1249
  case "08000":
@@ -1270,11 +1264,11 @@ function fromPostgresError(error) {
1270
1264
  case "23000":
1271
1265
  // integrity_constraint_violation
1272
1266
  case "23001":
1273
- return new ValidationError(message, { code, constraint: "integrity" });
1267
+ return new ConstraintViolationError(message, { code, constraint: "integrity" });
1274
1268
  case "23502":
1275
- return new ValidationError(message, { code, constraint: "not_null" });
1269
+ return new ConstraintViolationError(message, { code, constraint: "not_null" });
1276
1270
  case "23503":
1277
- return new ValidationError(message, { code, constraint: "foreign_key" });
1271
+ return new ConstraintViolationError(message, { code, constraint: "foreign_key" });
1278
1272
  case "23505":
1279
1273
  const parsed = parseUniqueViolation(message);
1280
1274
  if (parsed) {
@@ -1282,7 +1276,7 @@ function fromPostgresError(error) {
1282
1276
  }
1283
1277
  return new DuplicateEntryError("field", "value");
1284
1278
  case "23514":
1285
- return new ValidationError(message, { code, constraint: "check" });
1279
+ return new ConstraintViolationError(message, { code, constraint: "check" });
1286
1280
  // Class 40 — Transaction Rollback
1287
1281
  case "40000":
1288
1282
  // transaction_rollback
@@ -1365,8 +1359,8 @@ async function createDatabaseConnection(connectionString, poolConfig, retryConfi
1365
1359
  dbLogger.info("Database connected successfully");
1366
1360
  }
1367
1361
  return client;
1368
- } catch (error) {
1369
- lastError = fromPostgresError(error);
1362
+ } catch (error2) {
1363
+ lastError = fromPostgresError(error2);
1370
1364
  if (attempt < retryConfig.maxRetries) {
1371
1365
  const delayMs = Math.min(
1372
1366
  retryConfig.initialDelay * Math.pow(retryConfig.factor, attempt),
@@ -1392,8 +1386,8 @@ async function checkConnection(client) {
1392
1386
  try {
1393
1387
  await client`SELECT 1 as health_check`;
1394
1388
  return true;
1395
- } catch (error) {
1396
- dbLogger.error("Database health check failed", error);
1389
+ } catch (error2) {
1390
+ dbLogger.error("Database health check failed", error2);
1397
1391
  return false;
1398
1392
  }
1399
1393
  }
@@ -1563,8 +1557,8 @@ async function createDatabaseFromEnv(options) {
1563
1557
  dbLogger2.warn("No database pattern detected");
1564
1558
  return { write: void 0, read: void 0 };
1565
1559
  }
1566
- } catch (error) {
1567
- const message = error instanceof Error ? error.message : "Unknown error";
1560
+ } catch (error2) {
1561
+ const message = error2 instanceof Error ? error2.message : "Unknown error";
1568
1562
  dbLogger2.error("Failed to create database connection", {
1569
1563
  error: message,
1570
1564
  stage: "initialization",
@@ -1573,7 +1567,7 @@ async function createDatabaseFromEnv(options) {
1573
1567
  hasUrl: !!process.env.DATABASE_URL,
1574
1568
  hasReplicaUrl: !!process.env.DATABASE_REPLICA_URL
1575
1569
  });
1576
- throw new Error(`Database connection failed: ${message}`, { cause: error });
1570
+ throw new Error(`Database connection failed: ${message}`, { cause: error2 });
1577
1571
  }
1578
1572
  }
1579
1573
  var dbLogger2;
@@ -1638,8 +1632,8 @@ function startHealthCheck(config, options, getDatabase2, closeDatabase2) {
1638
1632
  if (read && read !== write) {
1639
1633
  await read.execute("SELECT 1");
1640
1634
  }
1641
- } catch (error) {
1642
- const message = error instanceof Error ? error.message : "Unknown error";
1635
+ } catch (error2) {
1636
+ const message = error2 instanceof Error ? error2.message : "Unknown error";
1643
1637
  dbLogger3.error("Database health check failed", { error: message });
1644
1638
  if (config.reconnect) {
1645
1639
  await attemptReconnection(config, options, closeDatabase2);
@@ -1668,8 +1662,8 @@ async function attemptReconnection(config, options, closeDatabase2) {
1668
1662
  dbLogger3.info("Database reconnection successful", { attempt });
1669
1663
  return;
1670
1664
  }
1671
- } catch (error) {
1672
- const message = error instanceof Error ? error.message : "Unknown error";
1665
+ } catch (error2) {
1666
+ const message = error2 instanceof Error ? error2.message : "Unknown error";
1673
1667
  dbLogger3.error(`Reconnection attempt ${attempt} failed`, {
1674
1668
  error: message,
1675
1669
  attempt,
@@ -1746,11 +1740,11 @@ async function initDatabase(options) {
1746
1740
  logQueries: monConfig.logQueries
1747
1741
  });
1748
1742
  }
1749
- } catch (error) {
1750
- const message = error instanceof Error ? error.message : "Unknown error";
1743
+ } catch (error2) {
1744
+ const message = error2 instanceof Error ? error2.message : "Unknown error";
1751
1745
  dbLogger4.error("Database connection failed", { error: message });
1752
1746
  await closeDatabase();
1753
- throw new Error(`Database connection test failed: ${message}`, { cause: error });
1747
+ throw new Error(`Database connection test failed: ${message}`, { cause: error2 });
1754
1748
  }
1755
1749
  } else {
1756
1750
  dbLogger4.warn("No database configuration found");
@@ -1784,9 +1778,9 @@ async function closeDatabase() {
1784
1778
  }
1785
1779
  await Promise.all(closePromises);
1786
1780
  dbLogger4.info("All database connections closed");
1787
- } catch (error) {
1788
- dbLogger4.error("Error during database cleanup", error);
1789
- throw error;
1781
+ } catch (error2) {
1782
+ dbLogger4.error("Error during database cleanup", error2);
1783
+ throw error2;
1790
1784
  } finally {
1791
1785
  setWriteInstance(void 0);
1792
1786
  setReadInstance(void 0);
@@ -1892,7 +1886,7 @@ function discoverPackageSchemas(cwd) {
1892
1886
  ...Object.keys(projectPkg.dependencies || {}),
1893
1887
  ...Object.keys(projectPkg.devDependencies || {})
1894
1888
  ]);
1895
- } catch (error) {
1889
+ } catch (error2) {
1896
1890
  }
1897
1891
  }
1898
1892
  const checkPackage = (_pkgName, pkgPath) => {
@@ -1911,7 +1905,7 @@ function discoverPackageSchemas(cwd) {
1911
1905
  schemas.push(...schemaFiles);
1912
1906
  }
1913
1907
  }
1914
- } catch (error) {
1908
+ } catch (error2) {
1915
1909
  }
1916
1910
  };
1917
1911
  const spfnDir = join(nodeModulesPath, "@spfn");
@@ -1921,7 +1915,7 @@ function discoverPackageSchemas(cwd) {
1921
1915
  for (const pkg of spfnPackages) {
1922
1916
  checkPackage(`@spfn/${pkg}`, join(spfnDir, pkg));
1923
1917
  }
1924
- } catch (error) {
1918
+ } catch (error2) {
1925
1919
  }
1926
1920
  }
1927
1921
  for (const depName of directDeps) {
@@ -2165,9 +2159,9 @@ function Transactional(options = {}) {
2165
2159
  });
2166
2160
  }
2167
2161
  }
2168
- } catch (error) {
2162
+ } catch (error2) {
2169
2163
  const duration = Date.now() - startTime;
2170
- const customError = error instanceof TransactionError ? error : fromPostgresError(error);
2164
+ const customError = error2 instanceof TransactionError ? error2 : fromPostgresError(error2);
2171
2165
  if (enableLogging) {
2172
2166
  txLogger2.error("Transaction rolled back", {
2173
2167
  txId,
@@ -2389,110 +2383,149 @@ var init_db = __esm({
2389
2383
  }
2390
2384
  });
2391
2385
 
2392
- // src/cache/redis-factory.ts
2393
- function hasRedisConfig() {
2394
- return !!(process.env.REDIS_URL || process.env.REDIS_WRITE_URL || process.env.REDIS_READ_URL || process.env.REDIS_SENTINEL_HOSTS || process.env.REDIS_CLUSTER_NODES);
2386
+ // src/cache/cache-factory.ts
2387
+ function hasCacheConfig() {
2388
+ return !!// Modern (Valkey/Cache)
2389
+ (process.env.VALKEY_URL || process.env.CACHE_URL || process.env.VALKEY_WRITE_URL || process.env.VALKEY_READ_URL || process.env.CACHE_WRITE_URL || process.env.CACHE_READ_URL || process.env.VALKEY_SENTINEL_HOSTS || process.env.VALKEY_CLUSTER_NODES || // Legacy (Redis - backward compatibility)
2390
+ process.env.REDIS_URL || process.env.REDIS_WRITE_URL || process.env.REDIS_READ_URL || process.env.REDIS_SENTINEL_HOSTS || process.env.REDIS_CLUSTER_NODES);
2391
+ }
2392
+ function getEnv(valkeyKey, cacheKey, redisKey) {
2393
+ return process.env[valkeyKey] || process.env[cacheKey] || process.env[redisKey];
2395
2394
  }
2396
2395
  function createClient(RedisClient, url) {
2397
2396
  const options = {};
2398
- if (url.startsWith("rediss://")) {
2397
+ if (url.startsWith("rediss://") || url.startsWith("valkeys://")) {
2398
+ const rejectUnauthorized = getEnv(
2399
+ "VALKEY_TLS_REJECT_UNAUTHORIZED",
2400
+ "CACHE_TLS_REJECT_UNAUTHORIZED",
2401
+ "REDIS_TLS_REJECT_UNAUTHORIZED"
2402
+ );
2399
2403
  options.tls = {
2400
- rejectUnauthorized: process.env.REDIS_TLS_REJECT_UNAUTHORIZED !== "false"
2404
+ rejectUnauthorized: rejectUnauthorized !== "false"
2401
2405
  };
2402
2406
  }
2403
2407
  return new RedisClient(url, options);
2404
2408
  }
2405
- async function createRedisFromEnv() {
2406
- if (!hasRedisConfig()) {
2409
+ async function createCacheFromEnv() {
2410
+ if (!hasCacheConfig()) {
2411
+ cacheLogger.info("No cache configuration found - running without cache");
2407
2412
  return { write: void 0, read: void 0 };
2408
2413
  }
2409
2414
  try {
2410
2415
  const ioredis = await import('ioredis');
2411
2416
  const RedisClient = ioredis.default;
2412
- if (process.env.REDIS_URL && !process.env.REDIS_WRITE_URL && !process.env.REDIS_READ_URL && !process.env.REDIS_CLUSTER_NODES) {
2413
- const client = createClient(RedisClient, process.env.REDIS_URL);
2417
+ const singleUrl = getEnv("VALKEY_URL", "CACHE_URL", "REDIS_URL");
2418
+ const writeUrl = getEnv("VALKEY_WRITE_URL", "CACHE_WRITE_URL", "REDIS_WRITE_URL");
2419
+ const readUrl = getEnv("VALKEY_READ_URL", "CACHE_READ_URL", "REDIS_READ_URL");
2420
+ const clusterNodes = getEnv("VALKEY_CLUSTER_NODES", "CACHE_CLUSTER_NODES", "REDIS_CLUSTER_NODES");
2421
+ const sentinelHosts = getEnv("VALKEY_SENTINEL_HOSTS", "CACHE_SENTINEL_HOSTS", "REDIS_SENTINEL_HOSTS");
2422
+ const masterName = getEnv("VALKEY_MASTER_NAME", "CACHE_MASTER_NAME", "REDIS_MASTER_NAME");
2423
+ const password = getEnv("VALKEY_PASSWORD", "CACHE_PASSWORD", "REDIS_PASSWORD");
2424
+ if (singleUrl && !writeUrl && !readUrl && !clusterNodes) {
2425
+ const client = createClient(RedisClient, singleUrl);
2426
+ cacheLogger.debug("Created single cache instance", { url: singleUrl.replace(/:[^:@]+@/, ":***@") });
2414
2427
  return { write: client, read: client };
2415
2428
  }
2416
- if (process.env.REDIS_WRITE_URL && process.env.REDIS_READ_URL) {
2417
- const write = createClient(RedisClient, process.env.REDIS_WRITE_URL);
2418
- const read = createClient(RedisClient, process.env.REDIS_READ_URL);
2429
+ if (writeUrl && readUrl) {
2430
+ const write = createClient(RedisClient, writeUrl);
2431
+ const read = createClient(RedisClient, readUrl);
2432
+ cacheLogger.debug("Created master-replica cache instances");
2419
2433
  return { write, read };
2420
2434
  }
2421
- if (process.env.REDIS_SENTINEL_HOSTS && process.env.REDIS_MASTER_NAME) {
2422
- const sentinels = process.env.REDIS_SENTINEL_HOSTS.split(",").map((host) => {
2435
+ if (sentinelHosts && masterName) {
2436
+ const sentinels = sentinelHosts.split(",").map((host) => {
2423
2437
  const [hostname, port] = host.trim().split(":");
2424
2438
  return { host: hostname, port: Number(port) || 26379 };
2425
2439
  });
2426
2440
  const options = {
2427
2441
  sentinels,
2428
- name: process.env.REDIS_MASTER_NAME,
2429
- password: process.env.REDIS_PASSWORD
2442
+ name: masterName,
2443
+ password
2430
2444
  };
2431
2445
  const client = new RedisClient(options);
2446
+ cacheLogger.debug("Created sentinel cache instance", { masterName, sentinels: sentinels.length });
2432
2447
  return { write: client, read: client };
2433
2448
  }
2434
- if (process.env.REDIS_CLUSTER_NODES) {
2435
- const nodes = process.env.REDIS_CLUSTER_NODES.split(",").map((node) => {
2449
+ if (clusterNodes) {
2450
+ const nodes = clusterNodes.split(",").map((node) => {
2436
2451
  const [host, port] = node.trim().split(":");
2437
2452
  return { host, port: Number(port) || 6379 };
2438
2453
  });
2439
2454
  const clusterOptions = {
2440
2455
  redisOptions: {
2441
- password: process.env.REDIS_PASSWORD
2456
+ password
2442
2457
  }
2443
2458
  };
2444
2459
  const cluster = new RedisClient.Cluster(nodes, clusterOptions);
2460
+ cacheLogger.debug("Created cluster cache instance", { nodes: nodes.length });
2445
2461
  return { write: cluster, read: cluster };
2446
2462
  }
2447
- if (process.env.REDIS_URL) {
2448
- const client = createClient(RedisClient, process.env.REDIS_URL);
2463
+ if (singleUrl) {
2464
+ const client = createClient(RedisClient, singleUrl);
2465
+ cacheLogger.debug("Created cache instance (fallback)", { url: singleUrl.replace(/:[^:@]+@/, ":***@") });
2449
2466
  return { write: client, read: client };
2450
2467
  }
2468
+ cacheLogger.info("No valid cache configuration found - running without cache");
2451
2469
  return { write: void 0, read: void 0 };
2452
- } catch (error) {
2453
- if (error instanceof Error) {
2454
- cacheLogger.warn(
2455
- "Failed to create Redis client",
2456
- error,
2457
- { suggestion: "Using memory-only cache. Install ioredis: npm install ioredis" }
2458
- );
2470
+ } catch (error2) {
2471
+ if (error2 instanceof Error) {
2472
+ if (error2.message.includes("Cannot find module")) {
2473
+ cacheLogger.warn(
2474
+ "Cache client library not installed",
2475
+ error2,
2476
+ {
2477
+ suggestion: "Install ioredis to enable cache: pnpm install ioredis",
2478
+ mode: "disabled"
2479
+ }
2480
+ );
2481
+ } else {
2482
+ cacheLogger.warn(
2483
+ "Failed to create cache client",
2484
+ error2,
2485
+ { mode: "disabled" }
2486
+ );
2487
+ }
2459
2488
  } else {
2460
2489
  cacheLogger.warn(
2461
- "Failed to create Redis client",
2462
- { error: String(error), suggestion: "Using memory-only cache. Install ioredis: npm install ioredis" }
2490
+ "Failed to create cache client",
2491
+ { error: String(error2), mode: "disabled" }
2463
2492
  );
2464
2493
  }
2465
2494
  return { write: void 0, read: void 0 };
2466
2495
  }
2467
2496
  }
2468
- async function createSingleRedisFromEnv() {
2469
- const { write } = await createRedisFromEnv();
2497
+ async function createSingleCacheFromEnv() {
2498
+ const { write } = await createCacheFromEnv();
2470
2499
  return write;
2471
2500
  }
2472
2501
  var cacheLogger;
2473
- var init_redis_factory = __esm({
2474
- "src/cache/redis-factory.ts"() {
2502
+ var init_cache_factory = __esm({
2503
+ "src/cache/cache-factory.ts"() {
2475
2504
  init_logger2();
2476
2505
  cacheLogger = logger.child("cache");
2477
2506
  }
2478
2507
  });
2479
2508
 
2480
- // src/cache/redis-manager.ts
2481
- function getRedis() {
2509
+ // src/cache/cache-manager.ts
2510
+ function getCache() {
2482
2511
  return writeInstance;
2483
2512
  }
2484
- function getRedisRead() {
2513
+ function getCacheRead() {
2485
2514
  return readInstance ?? writeInstance;
2486
2515
  }
2487
- function setRedis(write, read) {
2516
+ function isCacheDisabled() {
2517
+ return isDisabled;
2518
+ }
2519
+ function setCache(write, read) {
2488
2520
  writeInstance = write;
2489
2521
  readInstance = read ?? write;
2522
+ isDisabled = !write;
2490
2523
  }
2491
- async function initRedis() {
2524
+ async function initCache() {
2492
2525
  if (writeInstance) {
2493
- return { write: writeInstance, read: readInstance };
2526
+ return { write: writeInstance, read: readInstance, disabled: isDisabled };
2494
2527
  }
2495
- const { write, read } = await createRedisFromEnv();
2528
+ const { write, read } = await createCacheFromEnv();
2496
2529
  if (write) {
2497
2530
  try {
2498
2531
  await write.ping();
@@ -2501,14 +2534,18 @@ async function initRedis() {
2501
2534
  }
2502
2535
  writeInstance = write;
2503
2536
  readInstance = read;
2537
+ isDisabled = false;
2504
2538
  const hasReplica = read && read !== write;
2505
2539
  cacheLogger2.info(
2506
- hasReplica ? "Redis connected (Master-Replica)" : "Redis connected"
2540
+ hasReplica ? "Cache connected (Master-Replica)" : "Cache connected",
2541
+ { mode: "enabled" }
2507
2542
  );
2508
- } catch (error) {
2543
+ return { write: writeInstance, read: readInstance, disabled: false };
2544
+ } catch (error2) {
2509
2545
  cacheLogger2.error(
2510
- "Redis connection failed",
2511
- error instanceof Error ? error : new Error(String(error))
2546
+ "Cache connection failed - running in disabled mode",
2547
+ error2 instanceof Error ? error2 : new Error(String(error2)),
2548
+ { mode: "disabled" }
2512
2549
  );
2513
2550
  try {
2514
2551
  await write.quit();
@@ -2517,64 +2554,91 @@ async function initRedis() {
2517
2554
  }
2518
2555
  } catch {
2519
2556
  }
2520
- return { write: void 0, read: void 0 };
2557
+ isDisabled = true;
2558
+ return { write: void 0, read: void 0, disabled: true };
2521
2559
  }
2522
2560
  }
2523
- return { write: writeInstance, read: readInstance };
2561
+ isDisabled = true;
2562
+ cacheLogger2.info("Cache disabled - no configuration or library not installed", { mode: "disabled" });
2563
+ return { write: void 0, read: void 0, disabled: true };
2524
2564
  }
2525
- async function closeRedis() {
2565
+ async function closeCache() {
2566
+ if (isDisabled) {
2567
+ cacheLogger2.debug("Cache already disabled, nothing to close");
2568
+ return;
2569
+ }
2526
2570
  const closePromises = [];
2527
2571
  if (writeInstance) {
2528
2572
  closePromises.push(
2529
2573
  writeInstance.quit().catch((err) => {
2530
- cacheLogger2.error("Error closing Redis write instance", err);
2574
+ cacheLogger2.error("Error closing cache write instance", err);
2531
2575
  })
2532
2576
  );
2533
2577
  }
2534
2578
  if (readInstance && readInstance !== writeInstance) {
2535
2579
  closePromises.push(
2536
2580
  readInstance.quit().catch((err) => {
2537
- cacheLogger2.error("Error closing Redis read instance", err);
2581
+ cacheLogger2.error("Error closing cache read instance", err);
2538
2582
  })
2539
2583
  );
2540
2584
  }
2541
2585
  await Promise.all(closePromises);
2542
2586
  writeInstance = void 0;
2543
2587
  readInstance = void 0;
2544
- cacheLogger2.info("Redis connections closed");
2588
+ isDisabled = true;
2589
+ cacheLogger2.info("Cache connections closed", { mode: "disabled" });
2545
2590
  }
2546
- function getRedisInfo() {
2591
+ function getCacheInfo() {
2547
2592
  return {
2548
2593
  hasWrite: !!writeInstance,
2549
2594
  hasRead: !!readInstance,
2550
- isReplica: !!(readInstance && readInstance !== writeInstance)
2595
+ isReplica: !!(readInstance && readInstance !== writeInstance),
2596
+ disabled: isDisabled
2551
2597
  };
2552
2598
  }
2553
- var cacheLogger2, writeInstance, readInstance;
2554
- var init_redis_manager = __esm({
2555
- "src/cache/redis-manager.ts"() {
2556
- init_redis_factory();
2599
+ var cacheLogger2, writeInstance, readInstance, isDisabled, getRedis, getRedisRead, setRedis, initRedis, closeRedis, getRedisInfo;
2600
+ var init_cache_manager = __esm({
2601
+ "src/cache/cache-manager.ts"() {
2602
+ init_cache_factory();
2557
2603
  init_logger2();
2558
2604
  cacheLogger2 = logger.child("cache");
2605
+ isDisabled = false;
2606
+ getRedis = getCache;
2607
+ getRedisRead = getCacheRead;
2608
+ setRedis = setCache;
2609
+ initRedis = initCache;
2610
+ closeRedis = closeCache;
2611
+ getRedisInfo = getCacheInfo;
2559
2612
  }
2560
2613
  });
2561
2614
 
2562
2615
  // src/cache/index.ts
2563
2616
  var cache_exports = {};
2564
2617
  __export(cache_exports, {
2618
+ closeCache: () => closeCache,
2565
2619
  closeRedis: () => closeRedis,
2566
- createRedisFromEnv: () => createRedisFromEnv,
2567
- createSingleRedisFromEnv: () => createSingleRedisFromEnv,
2620
+ createCacheFromEnv: () => createCacheFromEnv,
2621
+ createRedisFromEnv: () => createCacheFromEnv,
2622
+ createSingleCacheFromEnv: () => createSingleCacheFromEnv,
2623
+ createSingleRedisFromEnv: () => createSingleCacheFromEnv,
2624
+ getCache: () => getCache,
2625
+ getCacheInfo: () => getCacheInfo,
2626
+ getCacheRead: () => getCacheRead,
2568
2627
  getRedis: () => getRedis,
2569
2628
  getRedisInfo: () => getRedisInfo,
2570
2629
  getRedisRead: () => getRedisRead,
2630
+ initCache: () => initCache,
2571
2631
  initRedis: () => initRedis,
2632
+ isCacheDisabled: () => isCacheDisabled,
2633
+ setCache: () => setCache,
2572
2634
  setRedis: () => setRedis
2573
2635
  });
2574
2636
  var init_cache = __esm({
2575
2637
  "src/cache/index.ts"() {
2576
- init_redis_factory();
2577
- init_redis_manager();
2638
+ init_cache_factory();
2639
+ init_cache_manager();
2640
+ init_cache_manager();
2641
+ init_cache_factory();
2578
2642
  }
2579
2643
  });
2580
2644
 
@@ -2599,8 +2663,8 @@ var AutoRouteLoader = class {
2599
2663
  }
2600
2664
  let failureCount = 0;
2601
2665
  for (const file of files) {
2602
- const success = await this.loadRoute(app, file);
2603
- if (success) ; else {
2666
+ const success2 = await this.loadRoute(app, file);
2667
+ if (success2) ; else {
2604
2668
  failureCount++;
2605
2669
  }
2606
2670
  }
@@ -2616,14 +2680,15 @@ var AutoRouteLoader = class {
2616
2680
  }
2617
2681
  /**
2618
2682
  * Load routes from an external directory (e.g., from SPFN function packages)
2619
- * Routes use contract-based absolute paths, so no basePath prefix needed
2683
+ * Reads package.json spfn.prefix and mounts routes under that prefix
2620
2684
  *
2621
2685
  * @param app - Hono app instance
2622
2686
  * @param routesDir - Directory containing route handlers
2623
2687
  * @param packageName - Name of the package (for logging)
2688
+ * @param prefix - Optional prefix to mount routes under (from package.json spfn.prefix)
2624
2689
  * @returns Route statistics
2625
2690
  */
2626
- async loadExternalRoutes(app, routesDir, packageName) {
2691
+ async loadExternalRoutes(app, routesDir, packageName, prefix) {
2627
2692
  const startTime = Date.now();
2628
2693
  const tempRoutesDir = this.routesDir;
2629
2694
  this.routesDir = routesDir;
@@ -2636,8 +2701,8 @@ var AutoRouteLoader = class {
2636
2701
  let successCount = 0;
2637
2702
  let failureCount = 0;
2638
2703
  for (const file of files) {
2639
- const success = await this.loadRoute(app, file);
2640
- if (success) {
2704
+ const success2 = await this.loadRoute(app, file, prefix);
2705
+ if (success2) {
2641
2706
  successCount++;
2642
2707
  } else {
2643
2708
  failureCount++;
@@ -2647,6 +2712,7 @@ var AutoRouteLoader = class {
2647
2712
  if (this.debug) {
2648
2713
  routeLogger2.info("External routes loaded", {
2649
2714
  package: packageName,
2715
+ prefix: prefix || "/",
2650
2716
  total: successCount,
2651
2717
  failed: failureCount,
2652
2718
  elapsed: `${elapsed}ms`
@@ -2690,7 +2756,7 @@ var AutoRouteLoader = class {
2690
2756
  isValidRouteFile(fileName) {
2691
2757
  return fileName === "index.ts" || fileName === "index.js" || fileName === "index.mjs";
2692
2758
  }
2693
- async loadRoute(app, absolutePath) {
2759
+ async loadRoute(app, absolutePath, prefix) {
2694
2760
  const relativePath = relative(this.routesDir, absolutePath);
2695
2761
  try {
2696
2762
  const module = await import(absolutePath);
@@ -2706,11 +2772,24 @@ var AutoRouteLoader = class {
2706
2772
  return false;
2707
2773
  }
2708
2774
  const contractPaths = this.extractContractPaths(module);
2775
+ if (prefix) {
2776
+ const invalidPaths = contractPaths.filter((path) => !path.startsWith(prefix));
2777
+ if (invalidPaths.length > 0) {
2778
+ routeLogger2.error("Contract paths must include the package prefix", {
2779
+ file: relativePath,
2780
+ prefix,
2781
+ invalidPaths,
2782
+ hint: `Contract paths should start with "${prefix}". Example: path: "${prefix}/labels"`
2783
+ });
2784
+ return false;
2785
+ }
2786
+ }
2709
2787
  this.registerContractBasedMiddlewares(app, contractPaths, module);
2710
2788
  app.route("/", module.default);
2711
2789
  contractPaths.forEach((path) => {
2712
2790
  this.routes.push({
2713
2791
  path,
2792
+ // Use contract path as-is (already includes prefix)
2714
2793
  file: relativePath,
2715
2794
  meta: module.meta,
2716
2795
  priority: this.calculateContractPriority(path)
@@ -2721,8 +2800,8 @@ var AutoRouteLoader = class {
2721
2800
  }
2722
2801
  });
2723
2802
  return true;
2724
- } catch (error) {
2725
- this.categorizeAndLogError(error, relativePath);
2803
+ } catch (error2) {
2804
+ this.categorizeAndLogError(error2, relativePath);
2726
2805
  return false;
2727
2806
  }
2728
2807
  }
@@ -2778,9 +2857,9 @@ var AutoRouteLoader = class {
2778
2857
  }
2779
2858
  }
2780
2859
  }
2781
- categorizeAndLogError(error, relativePath) {
2782
- const message = error.message;
2783
- const stack = error.stack;
2860
+ categorizeAndLogError(error2, relativePath) {
2861
+ const message = error2.message;
2862
+ const stack = error2.stack;
2784
2863
  if (message.includes("Cannot find module") || message.includes("MODULE_NOT_FOUND")) {
2785
2864
  routeLogger2.error("Missing dependency", {
2786
2865
  file: relativePath,
@@ -2837,15 +2916,16 @@ async function loadRoutes(app, options) {
2837
2916
  routeLogger2.info("Loading function routes", { count: functionRoutes.length });
2838
2917
  for (const func of functionRoutes) {
2839
2918
  try {
2840
- await loader.loadExternalRoutes(app, func.routesDir, func.packageName);
2919
+ await loader.loadExternalRoutes(app, func.routesDir, func.packageName, func.prefix);
2841
2920
  routeLogger2.info("Function routes loaded", {
2842
2921
  package: func.packageName,
2843
- routesDir: func.routesDir
2922
+ routesDir: func.routesDir,
2923
+ prefix: func.prefix || "/"
2844
2924
  });
2845
- } catch (error) {
2925
+ } catch (error2) {
2846
2926
  routeLogger2.error("Failed to load function routes", {
2847
2927
  package: func.packageName,
2848
- error: error instanceof Error ? error.message : "Unknown error"
2928
+ error: error2 instanceof Error ? error2.message : "Unknown error"
2849
2929
  });
2850
2930
  }
2851
2931
  }
@@ -2856,87 +2936,6 @@ async function loadRoutes(app, options) {
2856
2936
 
2857
2937
  // src/route/bind.ts
2858
2938
  init_errors();
2859
- function bind(contract, handler) {
2860
- return async (rawContext) => {
2861
- let params = rawContext.req.param();
2862
- if (contract.params) {
2863
- params = Value.Convert(contract.params, params);
2864
- const errors = [...Value.Errors(contract.params, params)];
2865
- if (errors.length > 0) {
2866
- throw new ValidationError(
2867
- "Invalid path parameters",
2868
- {
2869
- fields: errors.map((e) => ({
2870
- path: e.path,
2871
- message: e.message,
2872
- value: e.value
2873
- }))
2874
- }
2875
- );
2876
- }
2877
- }
2878
- const url = new URL(rawContext.req.url);
2879
- let query = {};
2880
- url.searchParams.forEach((v, k) => {
2881
- const existing = query[k];
2882
- if (existing) {
2883
- query[k] = Array.isArray(existing) ? [...existing, v] : [existing, v];
2884
- } else {
2885
- query[k] = v;
2886
- }
2887
- });
2888
- if (contract.query) {
2889
- query = Value.Convert(contract.query, query);
2890
- const errors = [...Value.Errors(contract.query, query)];
2891
- if (errors.length > 0) {
2892
- throw new ValidationError(
2893
- "Invalid query parameters",
2894
- {
2895
- fields: errors.map((e) => ({
2896
- path: e.path,
2897
- message: e.message,
2898
- value: e.value
2899
- }))
2900
- }
2901
- );
2902
- }
2903
- }
2904
- const routeContext = {
2905
- params,
2906
- query,
2907
- data: async () => {
2908
- let body = await rawContext.req.json();
2909
- if (contract.body) {
2910
- body = Value.Convert(contract.body, body);
2911
- const errors = [...Value.Errors(contract.body, body)];
2912
- if (errors.length > 0) {
2913
- throw new ValidationError(
2914
- "Invalid request body",
2915
- {
2916
- fields: errors.map((e) => ({
2917
- path: e.path,
2918
- message: e.message,
2919
- value: e.value
2920
- }))
2921
- }
2922
- );
2923
- }
2924
- }
2925
- return body;
2926
- },
2927
- json: (data, status, headers) => {
2928
- return rawContext.json(data, status, headers);
2929
- },
2930
- raw: rawContext
2931
- };
2932
- return handler(routeContext);
2933
- };
2934
- }
2935
-
2936
- // src/route/types.ts
2937
- function isHttpMethod(value) {
2938
- return typeof value === "string" && ["GET", "POST", "PUT", "PATCH", "DELETE"].includes(value);
2939
- }
2940
2939
 
2941
2940
  // src/middleware/error-handler.ts
2942
2941
  init_logger2();
@@ -2961,6 +2960,7 @@ function ErrorHandler(options = {}) {
2961
2960
  });
2962
2961
  }
2963
2962
  const response = {
2963
+ success: false,
2964
2964
  error: {
2965
2965
  message: err.message || "Internal Server Error",
2966
2966
  type: errorType,
@@ -2989,22 +2989,6 @@ function generateRequestId() {
2989
2989
  const randomPart = randomBytes(6).toString("hex");
2990
2990
  return `req_${timestamp2}_${randomPart}`;
2991
2991
  }
2992
- function maskSensitiveData2(obj, sensitiveFields, seen = /* @__PURE__ */ new WeakSet()) {
2993
- if (!obj || typeof obj !== "object") return obj;
2994
- if (seen.has(obj)) return "[Circular]";
2995
- seen.add(obj);
2996
- const lowerFields = sensitiveFields.map((f) => f.toLowerCase());
2997
- const masked = Array.isArray(obj) ? [...obj] : { ...obj };
2998
- for (const key in masked) {
2999
- const lowerKey = key.toLowerCase();
3000
- if (lowerFields.some((field) => lowerKey.includes(field))) {
3001
- masked[key] = "***MASKED***";
3002
- } else if (typeof masked[key] === "object" && masked[key] !== null) {
3003
- masked[key] = maskSensitiveData2(masked[key], sensitiveFields, seen);
3004
- }
3005
- }
3006
- return masked;
3007
- }
3008
2992
  function RequestLogger(config) {
3009
2993
  const cfg = { ...DEFAULT_CONFIG, ...config };
3010
2994
  const apiLogger = logger.child("api");
@@ -3043,19 +3027,24 @@ function RequestLogger(config) {
3043
3027
  logData.slow = true;
3044
3028
  }
3045
3029
  apiLogger[logLevel]("Request completed", logData);
3046
- } catch (error) {
3030
+ } catch (error2) {
3047
3031
  const duration = Date.now() - startTime;
3048
- apiLogger.error("Request failed", error, {
3032
+ apiLogger.error("Request failed", error2, {
3049
3033
  requestId,
3050
3034
  method,
3051
3035
  path,
3052
3036
  duration
3053
3037
  });
3054
- throw error;
3038
+ throw error2;
3055
3039
  }
3056
3040
  };
3057
3041
  }
3058
3042
 
3043
+ // src/route/types.ts
3044
+ function isHttpMethod(value) {
3045
+ return typeof value === "string" && ["GET", "POST", "PUT", "PATCH", "DELETE"].includes(value);
3046
+ }
3047
+
3059
3048
  // src/server/create-server.ts
3060
3049
  init_logger2();
3061
3050
 
@@ -3076,9 +3065,9 @@ function createHealthCheckHandler(detailed) {
3076
3065
  try {
3077
3066
  await db.execute("SELECT 1");
3078
3067
  dbStatus = "connected";
3079
- } catch (error) {
3068
+ } catch (error2) {
3080
3069
  dbStatus = "error";
3081
- dbError = error instanceof Error ? error.message : String(error);
3070
+ dbError = error2 instanceof Error ? error2.message : String(error2);
3082
3071
  }
3083
3072
  }
3084
3073
  const redis = getRedis2();
@@ -3088,9 +3077,9 @@ function createHealthCheckHandler(detailed) {
3088
3077
  try {
3089
3078
  await redis.ping();
3090
3079
  redisStatus = "connected";
3091
- } catch (error) {
3080
+ } catch (error2) {
3092
3081
  redisStatus = "error";
3093
- redisError = error instanceof Error ? error.message : String(error);
3082
+ redisError = error2 instanceof Error ? error2.message : String(error2);
3094
3083
  }
3095
3084
  }
3096
3085
  response.services = {
@@ -3238,8 +3227,8 @@ async function executeBeforeRoutesHook(app, config) {
3238
3227
  }
3239
3228
  try {
3240
3229
  await config.beforeRoutes(app);
3241
- } catch (error) {
3242
- serverLogger.error("beforeRoutes hook failed", error);
3230
+ } catch (error2) {
3231
+ serverLogger.error("beforeRoutes hook failed", error2);
3243
3232
  throw new Error("Server initialization failed in beforeRoutes hook");
3244
3233
  }
3245
3234
  }
@@ -3257,8 +3246,8 @@ async function executeAfterRoutesHook(app, config) {
3257
3246
  }
3258
3247
  try {
3259
3248
  await config.afterRoutes(app);
3260
- } catch (error) {
3261
- serverLogger.error("afterRoutes hook failed", error);
3249
+ } catch (error2) {
3250
+ serverLogger.error("afterRoutes hook failed", error2);
3262
3251
  throw new Error("Server initialization failed in afterRoutes hook");
3263
3252
  }
3264
3253
  }
@@ -3378,11 +3367,11 @@ async function startServer(config) {
3378
3367
  await shutdownServer();
3379
3368
  }
3380
3369
  };
3381
- } catch (error) {
3382
- const err = error;
3370
+ } catch (error2) {
3371
+ const err = error2;
3383
3372
  serverLogger2.error("Server initialization failed", err);
3384
3373
  await cleanupOnFailure();
3385
- throw error;
3374
+ throw error2;
3386
3375
  }
3387
3376
  }
3388
3377
  async function loadAndMergeConfig(config) {
@@ -3480,8 +3469,8 @@ function createGracefulShutdown(shutdownServer, config) {
3480
3469
  ]);
3481
3470
  serverLogger2.info("Graceful shutdown completed successfully");
3482
3471
  process.exit(0);
3483
- } catch (error) {
3484
- const err = error;
3472
+ } catch (error2) {
3473
+ const err = error2;
3485
3474
  if (err.message && err.message.includes("timeout")) {
3486
3475
  serverLogger2.error("Graceful shutdown timeout, forcing exit", err);
3487
3476
  } else {
@@ -3494,8 +3483,8 @@ function createGracefulShutdown(shutdownServer, config) {
3494
3483
  function registerShutdownHandlers(shutdown) {
3495
3484
  process.on("SIGTERM", () => shutdown("SIGTERM"));
3496
3485
  process.on("SIGINT", () => shutdown("SIGINT"));
3497
- process.on("uncaughtException", (error) => {
3498
- serverLogger2.error("Uncaught exception", error);
3486
+ process.on("uncaughtException", (error2) => {
3487
+ serverLogger2.error("Uncaught exception", error2);
3499
3488
  shutdown("UNCAUGHT_EXCEPTION");
3500
3489
  });
3501
3490
  process.on("unhandledRejection", (reason, promise) => {
@@ -3517,13 +3506,6 @@ async function cleanupOnFailure() {
3517
3506
  }
3518
3507
  }
3519
3508
 
3520
- // src/index.ts
3521
- init_db();
3522
- init_cache();
3523
- init_transaction();
3524
- init_logger2();
3525
- init_errors();
3526
-
3527
- export { AutoRouteLoader, ConnectionError, DatabaseError, DeadlockError, DuplicateEntryError, ErrorHandler, NotFoundError, QueryError, RequestLogger, TransactionError, Transactional, ValidationError, bind, closeRedis, createRedisFromEnv, createServer, createSingleRedisFromEnv, detectDialect, foreignKey, fromPostgresError, generateDrizzleConfigFile, getDrizzleConfig, getRedis, getRedisInfo, getRedisRead, getTransaction, id, initRedis, isDatabaseError, isHttpMethod, loadRoutes, logger, maskSensitiveData2 as maskSensitiveData, optionalForeignKey, runWithTransaction, setRedis, startServer, timestamps };
3509
+ export { createServer, isHttpMethod, startServer };
3528
3510
  //# sourceMappingURL=index.js.map
3529
3511
  //# sourceMappingURL=index.js.map