@zudojs/database 0.1.0 → 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 (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -17
  3. package/dist/cache/cache.memory.d.ts +167 -0
  4. package/dist/cache/cache.memory.js +186 -40
  5. package/dist/cache/index.d.ts +2 -2
  6. package/dist/cache/index.js +2 -2
  7. package/dist/database/database.core.d.ts +91 -0
  8. package/dist/database/database.core.js +21 -4
  9. package/dist/databaseClient/databaseClient.core.d.ts +165 -14
  10. package/dist/databaseClient/databaseClient.core.js +304 -70
  11. package/dist/databaseClient/databaseClient.errors.d.ts +112 -0
  12. package/dist/databaseClient/databaseClient.errors.js +425 -0
  13. package/dist/databaseClient/index.d.ts +2 -1
  14. package/dist/databaseClient/index.js +2 -1
  15. package/dist/databaseConnection/databaseConnection.manager.d.ts +163 -0
  16. package/dist/databaseConnection/databaseConnection.manager.js +138 -76
  17. package/dist/databaseConnection/index.d.ts +1 -1
  18. package/dist/databaseType/databaseType.type.d.ts +224 -0
  19. package/dist/databaseType/databaseType.type.js +0 -35
  20. package/dist/health/health.check.d.ts +74 -0
  21. package/dist/health/health.check.js +78 -47
  22. package/dist/health/index.d.ts +1 -1
  23. package/dist/health/index.js +1 -1
  24. package/dist/index.d.ts +14 -14
  25. package/dist/index.js +11 -11
  26. package/dist/locks/index.d.ts +2 -2
  27. package/dist/locks/index.js +2 -2
  28. package/dist/locks/locks.core.d.ts +128 -0
  29. package/dist/locks/locks.core.js +144 -85
  30. package/dist/migration/index.d.ts +3 -1
  31. package/dist/migration/index.js +2 -0
  32. package/dist/migration/migration.dialect.d.ts +65 -0
  33. package/dist/migration/migration.dialect.js +63 -0
  34. package/dist/migration/migration.helpers.d.ts +65 -0
  35. package/dist/migration/migration.helpers.js +60 -18
  36. package/dist/migration/migration.runner.d.ts +75 -0
  37. package/dist/migration/migration.runner.js +195 -107
  38. package/dist/migration/migration.types.d.ts +85 -0
  39. package/dist/pagination/index.d.ts +2 -1
  40. package/dist/pagination/index.js +2 -1
  41. package/dist/pagination/pagination.core.d.ts +163 -0
  42. package/dist/pagination/pagination.core.js +78 -9
  43. package/dist/pagination/pagination.keyset.d.ts +55 -0
  44. package/dist/pagination/pagination.keyset.js +108 -0
  45. package/dist/queryBuilder/index.d.ts +4 -3
  46. package/dist/queryBuilder/index.js +3 -2
  47. package/dist/queryBuilder/queryBuilder.core.d.ts +178 -0
  48. package/dist/queryBuilder/queryBuilder.core.js +92 -14
  49. package/dist/queryBuilder/queryBuilder.factory.d.ts +6 -0
  50. package/dist/queryBuilder/queryBuilder.factory.js +0 -25
  51. package/dist/queryBuilder/queryBuilder.filter.d.ts +170 -0
  52. package/dist/queryBuilder/queryBuilder.filter.js +191 -30
  53. package/dist/queryBuilder/queryBuilder.prisma.d.ts +60 -0
  54. package/dist/queryBuilder/queryBuilder.prisma.js +233 -0
  55. package/dist/queryBuilder/queryBuilder.type.d.ts +48 -0
  56. package/dist/relations/index.d.ts +1 -1
  57. package/dist/relations/index.js +1 -1
  58. package/dist/relations/relations.definition.d.ts +184 -0
  59. package/dist/relations/relations.definition.js +186 -19
  60. package/dist/repository/index.d.ts +2 -1
  61. package/dist/repository/index.js +1 -0
  62. package/dist/repository/repository.base.d.ts +270 -0
  63. package/dist/repository/repository.base.js +350 -84
  64. package/dist/repository/repository.errors.d.ts +60 -0
  65. package/dist/repository/repository.errors.js +235 -0
  66. package/dist/seed/index.d.ts +2 -2
  67. package/dist/seed/index.js +1 -1
  68. package/dist/seed/seed.runner.d.ts +160 -0
  69. package/dist/seed/seed.runner.js +194 -225
  70. package/dist/transaction/index.d.ts +1 -1
  71. package/dist/transaction/index.js +1 -1
  72. package/dist/transaction/transaction.core.d.ts +117 -0
  73. package/dist/transaction/transaction.core.js +83 -56
  74. package/dist/unitOfWork/unitOfWork.core.d.ts +44 -0
  75. package/dist/unitOfWork/unitOfWork.core.js +9 -20
  76. package/package.json +40 -24
  77. package/dist/cache/cache.memory.d.ts.map +0 -1
  78. package/dist/cache/cache.memory.js.map +0 -1
  79. package/dist/cache/index.d.ts.map +0 -1
  80. package/dist/cache/index.js.map +0 -1
  81. package/dist/database/database.core.d.ts.map +0 -1
  82. package/dist/database/database.core.js.map +0 -1
  83. package/dist/database/index.d.ts.map +0 -1
  84. package/dist/database/index.js.map +0 -1
  85. package/dist/databaseClient/databaseClient.core.d.ts.map +0 -1
  86. package/dist/databaseClient/databaseClient.core.js.map +0 -1
  87. package/dist/databaseClient/databaseClient.logger.d.ts.map +0 -1
  88. package/dist/databaseClient/databaseClient.logger.js.map +0 -1
  89. package/dist/databaseClient/index.d.ts.map +0 -1
  90. package/dist/databaseClient/index.js.map +0 -1
  91. package/dist/databaseConnection/databaseConnection.manager.d.ts.map +0 -1
  92. package/dist/databaseConnection/databaseConnection.manager.js.map +0 -1
  93. package/dist/databaseConnection/index.d.ts.map +0 -1
  94. package/dist/databaseConnection/index.js.map +0 -1
  95. package/dist/databaseType/databaseType.type.d.ts.map +0 -1
  96. package/dist/databaseType/databaseType.type.js.map +0 -1
  97. package/dist/databaseType/index.d.ts.map +0 -1
  98. package/dist/databaseType/index.js.map +0 -1
  99. package/dist/health/health.check.d.ts.map +0 -1
  100. package/dist/health/health.check.js.map +0 -1
  101. package/dist/health/index.d.ts.map +0 -1
  102. package/dist/health/index.js.map +0 -1
  103. package/dist/index.d.ts.map +0 -1
  104. package/dist/index.js.map +0 -1
  105. package/dist/locks/index.d.ts.map +0 -1
  106. package/dist/locks/index.js.map +0 -1
  107. package/dist/locks/locks.core.d.ts.map +0 -1
  108. package/dist/locks/locks.core.js.map +0 -1
  109. package/dist/migration/index.d.ts.map +0 -1
  110. package/dist/migration/index.js.map +0 -1
  111. package/dist/migration/migration.helpers.d.ts.map +0 -1
  112. package/dist/migration/migration.helpers.js.map +0 -1
  113. package/dist/migration/migration.runner.d.ts.map +0 -1
  114. package/dist/migration/migration.runner.js.map +0 -1
  115. package/dist/migration/migration.types.d.ts.map +0 -1
  116. package/dist/migration/migration.types.js.map +0 -1
  117. package/dist/pagination/index.d.ts.map +0 -1
  118. package/dist/pagination/index.js.map +0 -1
  119. package/dist/pagination/pagination.core.d.ts.map +0 -1
  120. package/dist/pagination/pagination.core.js.map +0 -1
  121. package/dist/queryBuilder/index.d.ts.map +0 -1
  122. package/dist/queryBuilder/index.js.map +0 -1
  123. package/dist/queryBuilder/queryBuilder.core.d.ts.map +0 -1
  124. package/dist/queryBuilder/queryBuilder.core.js.map +0 -1
  125. package/dist/queryBuilder/queryBuilder.factory.d.ts.map +0 -1
  126. package/dist/queryBuilder/queryBuilder.factory.js.map +0 -1
  127. package/dist/queryBuilder/queryBuilder.filter.d.ts.map +0 -1
  128. package/dist/queryBuilder/queryBuilder.filter.js.map +0 -1
  129. package/dist/queryBuilder/queryBuilder.type.d.ts.map +0 -1
  130. package/dist/queryBuilder/queryBuilder.type.js.map +0 -1
  131. package/dist/relations/index.d.ts.map +0 -1
  132. package/dist/relations/index.js.map +0 -1
  133. package/dist/relations/relations.definition.d.ts.map +0 -1
  134. package/dist/relations/relations.definition.js.map +0 -1
  135. package/dist/repository/index.d.ts.map +0 -1
  136. package/dist/repository/index.js.map +0 -1
  137. package/dist/repository/repository.base.d.ts.map +0 -1
  138. package/dist/repository/repository.base.js.map +0 -1
  139. package/dist/seed/index.d.ts.map +0 -1
  140. package/dist/seed/index.js.map +0 -1
  141. package/dist/seed/seed.runner.d.ts.map +0 -1
  142. package/dist/seed/seed.runner.js.map +0 -1
  143. package/dist/transaction/index.d.ts.map +0 -1
  144. package/dist/transaction/index.js.map +0 -1
  145. package/dist/transaction/transaction.core.d.ts.map +0 -1
  146. package/dist/transaction/transaction.core.js.map +0 -1
  147. package/dist/unitOfWork/index.d.ts.map +0 -1
  148. package/dist/unitOfWork/index.js.map +0 -1
  149. package/dist/unitOfWork/unitOfWork.core.d.ts.map +0 -1
  150. package/dist/unitOfWork/unitOfWork.core.js.map +0 -1
@@ -1,9 +1,35 @@
1
- import { DatabaseError } from "@zudojs/errors";
2
- import { Prisma } from "@prisma/client";
1
+ import { DatabaseError, DatabaseOperation, ErrorCode } from "@zudojs/errors";
2
+ import { isDatabaseErrorLike, normalizeDatabaseError, } from "../databaseClient/databaseClient.errors.js";
3
3
  /**
4
4
  * Default database health-check timeout.
5
5
  */
6
6
  export const DEFAULT_HEALTH_TIMEOUT_MS = 5_000;
7
+ /**
8
+ * Error raised by {@link assertDatabaseHealth}. The underlying failure is
9
+ * preserved as `cause`.
10
+ */
11
+ export class DatabaseUnhealthyError extends DatabaseError {
12
+ health;
13
+ constructor(health, cause) {
14
+ super("Database health check failed.", {
15
+ code: ErrorCode.DATABASE_CONNECTION,
16
+ statusCode: 503,
17
+ operation: DatabaseOperation.CONNECT,
18
+ metadata: {
19
+ status: health.status,
20
+ latencyMs: health.latencyMs,
21
+ checkedAt: health.checkedAt.toISOString(),
22
+ ...(health.error?.code ? { errorCode: health.error.code } : {}),
23
+ ...(health.error?.databaseCode
24
+ ? { databaseCode: health.error.databaseCode }
25
+ : {}),
26
+ },
27
+ cause,
28
+ });
29
+ this.name = "DatabaseUnhealthyError";
30
+ this.health = health;
31
+ }
32
+ }
7
33
  /**
8
34
  * Performs a lightweight database health check.
9
35
  */
@@ -16,7 +42,7 @@ export async function checkDatabaseHealth(client, options = {}) {
16
42
  const startedAt = performance.now();
17
43
  try {
18
44
  await withTimeout(executeHealthCheck(client), timeoutMs);
19
- const latencyMs = Math.max(0, Math.round(performance.now() - startedAt));
45
+ const latencyMs = elapsed(startedAt);
20
46
  return {
21
47
  status: latencyMs > timeoutMs * 0.75 ? "degraded" : "healthy",
22
48
  healthy: true,
@@ -26,9 +52,9 @@ export async function checkDatabaseHealth(client, options = {}) {
26
52
  };
27
53
  }
28
54
  catch (error) {
29
- const latencyMs = Math.max(0, Math.round(performance.now() - startedAt));
55
+ const latencyMs = elapsed(startedAt);
30
56
  const normalizedError = normalizeHealthError(error);
31
- return {
57
+ const health = {
32
58
  status: "unhealthy",
33
59
  healthy: false,
34
60
  latencyMs,
@@ -36,8 +62,22 @@ export async function checkDatabaseHealth(client, options = {}) {
36
62
  message: normalizedError.message,
37
63
  error: normalizedError,
38
64
  };
65
+ Object.defineProperty(health, HEALTH_CAUSE, { value: error, enumerable: false });
66
+ return health;
39
67
  }
40
68
  }
69
+ /**
70
+ * Symbol under which the original failure is kept on an unhealthy result.
71
+ * It is a non-enumerable symbol key, so serialised health output never
72
+ * includes it.
73
+ */
74
+ const HEALTH_CAUSE = Symbol("zudojs.database.healthCause");
75
+ /**
76
+ * Returns the original error that made a health check fail, if any.
77
+ */
78
+ export function getHealthCheckCause(health) {
79
+ return health[HEALTH_CAUSE];
80
+ }
41
81
  /**
42
82
  * Performs a database readiness check.
43
83
  *
@@ -53,38 +93,30 @@ export async function checkDatabaseReadiness(client, options = {}) {
53
93
  const startedAt = performance.now();
54
94
  try {
55
95
  await withTimeout(executeHealthCheck(client), timeoutMs);
56
- const latencyMs = Math.max(0, Math.round(performance.now() - startedAt));
57
96
  return {
58
97
  ready: true,
59
98
  checkedAt,
60
- latencyMs,
99
+ latencyMs: elapsed(startedAt),
61
100
  message: "Database is ready.",
62
101
  };
63
102
  }
64
103
  catch (error) {
65
- const latencyMs = Math.max(0, Math.round(performance.now() - startedAt));
66
104
  return {
67
105
  ready: false,
68
106
  checkedAt,
69
- latencyMs,
107
+ latencyMs: elapsed(startedAt),
70
108
  message: normalizeHealthError(error).message,
71
109
  };
72
110
  }
73
111
  }
74
112
  /**
75
- * Throws when the database is not healthy.
113
+ * Throws a {@link DatabaseUnhealthyError} (with the real failure as
114
+ * `cause`) when the database is not healthy.
76
115
  */
77
116
  export async function assertDatabaseHealth(client, options = {}) {
78
117
  const health = await checkDatabaseHealth(client, options);
79
118
  if (!health.healthy) {
80
- throw new DatabaseError("Database health check failed.", {
81
- metadata: {
82
- status: health.status,
83
- latencyMs: health.latencyMs,
84
- checkedAt: health.checkedAt.toISOString(),
85
- },
86
- cause: health.error ? new Error(health.error.message) : undefined,
87
- });
119
+ throw new DatabaseUnhealthyError(health, getHealthCheckCause(health));
88
120
  }
89
121
  return health;
90
122
  }
@@ -96,21 +128,12 @@ export async function isDatabaseHealthy(client, options = {}) {
96
128
  return health.healthy;
97
129
  }
98
130
  /**
99
- * Executes the lightweight health query.
131
+ * Executes the lightweight health query. Errors are already normalised by
132
+ * the client, so they are passed through unchanged.
100
133
  */
101
134
  async function executeHealthCheck(client) {
102
- try {
103
- await client.queryRaw(Prisma.sql `SELECT 1 AS result`);
104
- }
105
- catch (error) {
106
- throw new DatabaseError("Database health query failed.", {
107
- cause: error,
108
- });
109
- }
135
+ await client.queryRawUnsafe("SELECT 1 AS result");
110
136
  }
111
- /**
112
- * Runs a promise with a timeout.
113
- */
114
137
  async function withTimeout(promise, timeoutMs) {
115
138
  let timeout;
116
139
  try {
@@ -118,42 +141,50 @@ async function withTimeout(promise, timeoutMs) {
118
141
  promise,
119
142
  new Promise((_resolve, reject) => {
120
143
  timeout = setTimeout(() => {
121
- reject(new DatabaseError(`Database health check timed out after ${timeoutMs}ms.`));
144
+ reject(new DatabaseError(`Database health check timed out after ${timeoutMs}ms.`, {
145
+ code: ErrorCode.DATABASE_TIMEOUT,
146
+ statusCode: 503,
147
+ operation: DatabaseOperation.QUERY,
148
+ metadata: { timeoutMs },
149
+ }));
122
150
  }, timeoutMs);
123
151
  }),
124
152
  ]);
125
153
  }
126
154
  finally {
127
- if (timeout) {
155
+ if (timeout)
128
156
  clearTimeout(timeout);
129
- }
130
157
  }
131
158
  }
132
- /**
133
- * Normalizes timeout values.
134
- */
135
159
  function normalizeTimeout(timeoutMs) {
136
- if (timeoutMs === undefined) {
160
+ if (timeoutMs === undefined)
137
161
  return DEFAULT_HEALTH_TIMEOUT_MS;
138
- }
139
162
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
140
163
  throw new TypeError("Database health timeout must be a positive finite number.");
141
164
  }
142
165
  return Math.floor(timeoutMs);
143
166
  }
167
+ function elapsed(startedAt) {
168
+ return Math.max(0, Math.round(performance.now() - startedAt));
169
+ }
144
170
  /**
145
- * Converts an unknown error into a safe health error.
171
+ * Converts an unknown error into a safe health error. Prisma errors are
172
+ * mapped so connection failures never leak host names.
146
173
  */
147
174
  function normalizeHealthError(error) {
148
- if (error instanceof Error) {
149
- return {
150
- name: error.name,
151
- message: error.message,
152
- };
153
- }
175
+ const normalized = isDatabaseErrorLike(error)
176
+ ? error
177
+ : normalizeDatabaseError(error, {
178
+ operation: DatabaseOperation.QUERY,
179
+ fallbackMessage: "Database health check failed.",
180
+ });
154
181
  return {
155
- name: "DatabaseHealthError",
156
- message: "Database health check failed.",
182
+ name: normalized.name,
183
+ message: normalized.message,
184
+ code: String(normalized.code),
185
+ ...(normalized.databaseCode !== undefined
186
+ ? { databaseCode: String(normalized.databaseCode) }
187
+ : {}),
157
188
  };
158
189
  }
159
190
  //# sourceMappingURL=health.check.js.map
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Database health and readiness monitoring.
5
5
  */
6
- export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, DEFAULT_HEALTH_TIMEOUT_MS, type DatabaseHealthStatus, type DatabaseHealth, type DatabaseHealthOptions, type DatabaseReadiness, } from "./health.check.js";
6
+ export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, getHealthCheckCause, DatabaseUnhealthyError, DEFAULT_HEALTH_TIMEOUT_MS, type DatabaseHealthStatus, type DatabaseHealth, type DatabaseHealthOptions, type DatabaseReadiness, } from "./health.check.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -3,5 +3,5 @@
3
3
  *
4
4
  * Database health and readiness monitoring.
5
5
  */
6
- export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, DEFAULT_HEALTH_TIMEOUT_MS, } from "./health.check.js";
6
+ export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, getHealthCheckCause, DatabaseUnhealthyError, DEFAULT_HEALTH_TIMEOUT_MS, } from "./health.check.js";
7
7
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -16,21 +16,21 @@
16
16
  * • Seed management
17
17
  * • Health and readiness checks
18
18
  */
19
- export type { DatabaseOperationOptions, DatabaseStatus, TransactionIsolationLevel, DatabaseOperation, DatabaseConnectionOptions, DatabaseHealth as DatabaseHealthInfo, DatabaseMetrics, TransactionOptions, TransactionCallback, Repository, PaginationInput, PaginationMeta, PaginatedResult, SortDirection, SortInput, QueryOptions, DatabaseEntity, SoftDeletableEntity, AuditableEntity, DatabaseErrorInfo, DatabaseLogger, } from "./databaseType/index.js";
19
+ export type { DatabaseOperationOptions, DatabaseStatus, TransactionIsolationLevel, DatabaseOperation, DatabaseConnectionOptions, DatabaseClientHealth, DatabaseHealth as DatabaseHealthInfo, TransactionOptions, TransactionCallback, Repository, SoftDeletableRepository, PaginationInput, PaginationMeta, PaginatedResult, SortDirection, SortInput, QueryOptions, DatabaseEntity, SoftDeletableEntity, AuditableEntity, DatabaseErrorInfo, DatabaseLogger, } from "./databaseType/index.js";
20
20
  export { noopDatabaseLogger } from "./databaseType/index.js";
21
- export { DatabaseClient, createDatabaseClient, type DatabaseClientOptions, type DatabaseTransactionContext, } from "./databaseClient/index.js";
22
- export { DatabaseConnectionManager, createConnectionManager, type DatabaseConnectionEvent, type DatabaseConnectionListener, type DatabaseConnectionEventDetails, type DatabaseConnectionManagerOptions, } from "./databaseConnection/index.js";
21
+ export { DatabaseClient, DatabaseAbortError, createDatabaseClient, buildPrismaTransactionOptions, createAbortError, raceAbort, throwIfAborted, SUPPORTED_ISOLATION_LEVELS, normalizeDatabaseError, withDatabaseErrorMetadata, isPrismaError, isRetryableTransactionError, isConflictError, isNotFoundError, getDatabaseErrorCode, getDatabaseErrorKind, isDatabaseErrorLike, toDatabaseErrorInfo, RETRYABLE_DATABASE_CODES, type DatabaseClientOptions, type DatabaseTransactionContext, type PrismaClientLike, type PrismaDriverAdapterLike, type PrismaQueryEvent, type PrismaTransactionOptions, type RawQueryOptions, type DatabaseErrorKind, type NormalizeDatabaseErrorOptions, type PrismaErrorLike, } from "./databaseClient/index.js";
22
+ export { DatabaseConnectionManager, createConnectionManager, type DatabaseConnectionEvent, type DatabaseConnectionListener, type DatabaseConnectionEventDetails, type DatabaseConnectionManagerOptions, type DatabaseReconnectOptions, } from "./databaseConnection/index.js";
23
23
  export { Database, createDatabase, getDatabase, connectDatabase, disconnectDatabase, resetDatabase, } from "./database/index.js";
24
- export { BaseRepository, type RepositoryDelegate, type BaseRepositoryOptions, } from "./repository/index.js";
25
- export { TransactionManager, createTransactionManager, withTransaction, withTransactionRetry, createTransactionContext, createTransactionId, isTransactionActive, isTransactionCommitted, isTransactionFailed, type TransactionStatus, type TransactionContext, type ManagedTransactionOptions, } from "./transaction/index.js";
24
+ export { BaseRepository, mapRepositoryError, isPrismaErrorLike, toDatabaseOperation, type RepositoryDelegate, type BaseRepositoryOptions, type SoftDeleteOptions, type CursorQueryOptions, type TransactionClientLike, type RepositoryOperation, type RepositoryErrorContext, } from "./repository/index.js";
25
+ export { TransactionManager, createTransactionManager, withTransaction, withTransactionRetry, createTransactionContext, createTransactionId, getTransactionContextFromError, isTransactionActive, isTransactionCommitted, isTransactionFailed, type TransactionStatus, type TransactionContext, type TransactionOutcome, type TransactionRetryOptions, type ManagedTransactionOptions, } from "./transaction/index.js";
26
26
  export { DatabaseUnitOfWork, createUnitOfWork, executeUnitOfWork, type UnitOfWork, type UnitOfWorkOptions, } from "./unitOfWork/index.js";
27
- export { QueryBuilder, createQueryBuilder, type QueryCondition, type QueryFilter, type QueryOperator, type QueryBuilderState, } from "./queryBuilder/index.js";
28
- export { equals, notEquals, inList, notInList, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, contains, startsWith, endsWith, isNull, isNotNull, and, or, not, condition, allOf, anyOf, fromObject, dateRange, oneOf, noneOf, optionalEquals, optionalContains, hasConditions, flattenAnd, cloneFilter, } from "./queryBuilder/index.js";
29
- export { normalizePagination, normalizePage, normalizeLimit, calculateOffset, calculateTotalPages, createPaginationMeta, createPaginatedResult, getNextPage, getPreviousPage, isValidPage, getItemRange, paginateCollection, encodeCursor, decodeCursor, normalizeCursorPagination, createCursorPaginationMeta, createCursorPaginatedResult, DEFAULT_PAGE, DEFAULT_LIMIT, MAX_LIMIT, type NormalizedPagination, type CursorPaginationInput, type CursorPaginationMeta, type CursorPaginatedResult, } from "./pagination/index.js";
30
- export { oneToOne, oneToMany, manyToOne, manyToMany, includeRelation, includeRelations, RelationRegistry, createRelationRegistry, validateRelation, isRelationType, isCollectionRelation, isSingleRelation, type RelationDefinition, type RelationType, type RelationLoadOptions, type RelationInclude, } from "./relations/index.js";
31
- export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, type DatabaseLockMode, type DatabaseLockOptions, type DatabaseLockResult, } from "./locks/index.js";
32
- export { MemoryDatabaseCache, createDatabaseCache, createCacheKey, serializeCachePart, getOrSet, invalidateByPrefix, type CacheEntry, type CacheOptions, type CacheStats, type DatabaseCache, } from "./cache/index.js";
33
- export { MigrationRunner, createMigrationRunner, normalizeMigrations, validateMigration, getLatestVersion, getCurrentVersion, DEFAULT_MIGRATION_TABLE, DEFAULT_MIGRATION_LOCK, type Migration, type MigrationRecord, type MigrationResult, type MigrationStatus, type MigrationRunnerOptions, } from "./migration/index.js";
34
- export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, type Seed, type SeedRecord, type SeedResult, type SeedRunnerOptions, } from "./seed/index.js";
35
- export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, DEFAULT_HEALTH_TIMEOUT_MS, type DatabaseHealthStatus, type DatabaseHealth, type DatabaseHealthOptions, type DatabaseReadiness, } from "./health/index.js";
27
+ export { QueryBuilder, createQueryBuilder, toPrismaWhere, toPrismaArgs, toPrismaOrderBy, toPrismaSelect, toPrismaSkipTake, type QueryCondition, type QueryFilter, type QueryOperator, type RelationOperator, type QueryBuilderState, type PrismaWhere, type PrismaQueryArgs, type ToPrismaArgsOptions, } from "./queryBuilder/index.js";
28
+ export { equals, notEquals, inList, notInList, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, contains, startsWith, endsWith, isNull, isNotNull, and, or, not, condition, allOf, anyOf, fromObject, dateRange, oneOf, noneOf, optionalEquals, optionalContains, hasConditions, flattenAnd, cloneFilter, between, matchesPattern, isEmpty, isNotEmpty, dateOnly, isBefore, isAfter, isBetween, notCondition, relational, } from "./queryBuilder/index.js";
29
+ export { normalizePagination, normalizePage, normalizeLimit, calculateOffset, calculateTotalPages, createPaginationMeta, createPaginatedResult, getNextPage, getPreviousPage, isValidPage, getItemRange, paginateCollection, encodeCursor, decodeCursor, validateCursorPayload, decodeKeysetCursor, buildKeysetWhere, createKeysetCursor, createKeysetPage, normalizeCursorPagination, createCursorPaginationMeta, createCursorPaginatedResult, DEFAULT_PAGE, DEFAULT_LIMIT, MAX_LIMIT, type NormalizedPagination, type CursorPaginationInput, type CursorPaginationMeta, type CursorPaginatedResult, type CursorPayload, type EncodeCursorOptions, type DecodeCursorOptions, type KeysetPageOptions, type KeysetWhere, } from "./pagination/index.js";
30
+ export { oneToOne, oneToMany, manyToOne, manyToMany, includeRelation, includeRelations, RelationRegistry, createRelationRegistry, validateRelation, validateInclude, toPrismaInclude, DEFAULT_INCLUDE_DEPTH, isRelationType, isCollectionRelation, isSingleRelation, type RelationDefinition, type RelationType, type RelationLoadOptions, type RelationInclude, type ToPrismaIncludeOptions, } from "./relations/index.js";
31
+ export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, normalizeAdvisoryKeyPair, resolveLockTransactionOptions, type DatabaseLockMode, type DatabaseLockOptions, type DatabaseLockResult, } from "./locks/index.js";
32
+ export { MemoryDatabaseCache, createDatabaseCache, createCacheKey, escapeCachePart, serializeCachePart, getOrSet, invalidateByPrefix, CACHE_KEY_SEPARATOR, type CacheEntry, type CacheOptions, type MemoryCacheOptions, type CacheStats, type DatabaseCache, } from "./cache/index.js";
33
+ export { MigrationRunner, createMigrationRunner, normalizeMigrations, validateMigration, getLatestVersion, getCurrentVersion, DEFAULT_MIGRATION_TABLE, DEFAULT_MIGRATION_LOCK, SQL_IDENTIFIER_PATTERN, validateIdentifier, validateLockKey, quoteIdentifier, hashLockKey, fnv1a64, getSqlDialect, isSqlDialectName, UnsupportedDialectError, DEFAULT_SQL_DIALECT, type Migration, type MigrationRecord, type MigrationResult, type MigrationStatus, type MigrationRunnerOptions, type RunnerTransactionOptions, type SqlDialect, type SqlDialectName, } from "./migration/index.js";
34
+ export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, type Seed, type SeedRecord, type SeedResult, type SeedStatus, type SeedRunnerOptions, } from "./seed/index.js";
35
+ export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, getHealthCheckCause, DatabaseUnhealthyError, DEFAULT_HEALTH_TIMEOUT_MS, type DatabaseHealthStatus, type DatabaseHealth, type DatabaseHealthOptions, type DatabaseReadiness, } from "./health/index.js";
36
36
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -18,32 +18,32 @@
18
18
  */
19
19
  export { noopDatabaseLogger } from "./databaseType/index.js";
20
20
  // Client
21
- export { DatabaseClient, createDatabaseClient, } from "./databaseClient/index.js";
21
+ export { DatabaseClient, DatabaseAbortError, createDatabaseClient, buildPrismaTransactionOptions, createAbortError, raceAbort, throwIfAborted, SUPPORTED_ISOLATION_LEVELS, normalizeDatabaseError, withDatabaseErrorMetadata, isPrismaError, isRetryableTransactionError, isConflictError, isNotFoundError, getDatabaseErrorCode, getDatabaseErrorKind, isDatabaseErrorLike, toDatabaseErrorInfo, RETRYABLE_DATABASE_CODES, } from "./databaseClient/index.js";
22
22
  // Connection
23
23
  export { DatabaseConnectionManager, createConnectionManager, } from "./databaseConnection/index.js";
24
24
  // Database facade
25
25
  export { Database, createDatabase, getDatabase, connectDatabase, disconnectDatabase, resetDatabase, } from "./database/index.js";
26
26
  // Repository
27
- export { BaseRepository, } from "./repository/index.js";
27
+ export { BaseRepository, mapRepositoryError, isPrismaErrorLike, toDatabaseOperation, } from "./repository/index.js";
28
28
  // Transactions
29
- export { TransactionManager, createTransactionManager, withTransaction, withTransactionRetry, createTransactionContext, createTransactionId, isTransactionActive, isTransactionCommitted, isTransactionFailed, } from "./transaction/index.js";
29
+ export { TransactionManager, createTransactionManager, withTransaction, withTransactionRetry, createTransactionContext, createTransactionId, getTransactionContextFromError, isTransactionActive, isTransactionCommitted, isTransactionFailed, } from "./transaction/index.js";
30
30
  // Unit of Work
31
31
  export { DatabaseUnitOfWork, createUnitOfWork, executeUnitOfWork, } from "./unitOfWork/index.js";
32
32
  // Query Builder
33
- export { QueryBuilder, createQueryBuilder, } from "./queryBuilder/index.js";
34
- export { equals, notEquals, inList, notInList, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, contains, startsWith, endsWith, isNull, isNotNull, and, or, not, condition, allOf, anyOf, fromObject, dateRange, oneOf, noneOf, optionalEquals, optionalContains, hasConditions, flattenAnd, cloneFilter, } from "./queryBuilder/index.js";
33
+ export { QueryBuilder, createQueryBuilder, toPrismaWhere, toPrismaArgs, toPrismaOrderBy, toPrismaSelect, toPrismaSkipTake, } from "./queryBuilder/index.js";
34
+ export { equals, notEquals, inList, notInList, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual, contains, startsWith, endsWith, isNull, isNotNull, and, or, not, condition, allOf, anyOf, fromObject, dateRange, oneOf, noneOf, optionalEquals, optionalContains, hasConditions, flattenAnd, cloneFilter, between, matchesPattern, isEmpty, isNotEmpty, dateOnly, isBefore, isAfter, isBetween, notCondition, relational, } from "./queryBuilder/index.js";
35
35
  // Pagination
36
- export { normalizePagination, normalizePage, normalizeLimit, calculateOffset, calculateTotalPages, createPaginationMeta, createPaginatedResult, getNextPage, getPreviousPage, isValidPage, getItemRange, paginateCollection, encodeCursor, decodeCursor, normalizeCursorPagination, createCursorPaginationMeta, createCursorPaginatedResult, DEFAULT_PAGE, DEFAULT_LIMIT, MAX_LIMIT, } from "./pagination/index.js";
36
+ export { normalizePagination, normalizePage, normalizeLimit, calculateOffset, calculateTotalPages, createPaginationMeta, createPaginatedResult, getNextPage, getPreviousPage, isValidPage, getItemRange, paginateCollection, encodeCursor, decodeCursor, validateCursorPayload, decodeKeysetCursor, buildKeysetWhere, createKeysetCursor, createKeysetPage, normalizeCursorPagination, createCursorPaginationMeta, createCursorPaginatedResult, DEFAULT_PAGE, DEFAULT_LIMIT, MAX_LIMIT, } from "./pagination/index.js";
37
37
  // Relations
38
- export { oneToOne, oneToMany, manyToOne, manyToMany, includeRelation, includeRelations, RelationRegistry, createRelationRegistry, validateRelation, isRelationType, isCollectionRelation, isSingleRelation, } from "./relations/index.js";
38
+ export { oneToOne, oneToMany, manyToOne, manyToMany, includeRelation, includeRelations, RelationRegistry, createRelationRegistry, validateRelation, validateInclude, toPrismaInclude, DEFAULT_INCLUDE_DEPTH, isRelationType, isCollectionRelation, isSingleRelation, } from "./relations/index.js";
39
39
  // Locks
40
- export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, } from "./locks/index.js";
40
+ export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, normalizeAdvisoryKeyPair, resolveLockTransactionOptions, } from "./locks/index.js";
41
41
  // Cache
42
- export { MemoryDatabaseCache, createDatabaseCache, createCacheKey, serializeCachePart, getOrSet, invalidateByPrefix, } from "./cache/index.js";
42
+ export { MemoryDatabaseCache, createDatabaseCache, createCacheKey, escapeCachePart, serializeCachePart, getOrSet, invalidateByPrefix, CACHE_KEY_SEPARATOR, } from "./cache/index.js";
43
43
  // Migrations
44
- export { MigrationRunner, createMigrationRunner, normalizeMigrations, validateMigration, getLatestVersion, getCurrentVersion, DEFAULT_MIGRATION_TABLE, DEFAULT_MIGRATION_LOCK, } from "./migration/index.js";
44
+ export { MigrationRunner, createMigrationRunner, normalizeMigrations, validateMigration, getLatestVersion, getCurrentVersion, DEFAULT_MIGRATION_TABLE, DEFAULT_MIGRATION_LOCK, SQL_IDENTIFIER_PATTERN, validateIdentifier, validateLockKey, quoteIdentifier, hashLockKey, fnv1a64, getSqlDialect, isSqlDialectName, UnsupportedDialectError, DEFAULT_SQL_DIALECT, } from "./migration/index.js";
45
45
  // Seeds
46
46
  export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, } from "./seed/index.js";
47
47
  // Health
48
- export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, DEFAULT_HEALTH_TIMEOUT_MS, } from "./health/index.js";
48
+ export { checkDatabaseHealth, checkDatabaseReadiness, assertDatabaseHealth, isDatabaseHealthy, getHealthCheckCause, DatabaseUnhealthyError, DEFAULT_HEALTH_TIMEOUT_MS, } from "./health/index.js";
49
49
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @zudojs/database — Locks
3
3
  *
4
- * Advisory and row-level database locking.
4
+ * Advisory and row-level database locking (PostgreSQL).
5
5
  */
6
- export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, type DatabaseLockMode, type DatabaseLockOptions, type DatabaseLockResult, } from "./locks.core.js";
6
+ export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, normalizeAdvisoryKeyPair, resolveLockTransactionOptions, type DatabaseLockMode, type DatabaseLockOptions, type DatabaseLockResult, } from "./locks.core.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @zudojs/database — Locks
3
3
  *
4
- * Advisory and row-level database locking.
4
+ * Advisory and row-level database locking (PostgreSQL).
5
5
  */
6
- export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, } from "./locks.core.js";
6
+ export { DatabaseLockManager, createLockManager, acquireAdvisoryLock, lockRow, buildLockClause, normalizeAdvisoryKey, normalizeAdvisoryKeyPair, resolveLockTransactionOptions, } from "./locks.core.js";
7
7
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,128 @@
1
+ import type { DatabaseClient, DatabaseTransactionContext } from "../databaseClient/databaseClient.core.js";
2
+ import type { TransactionOptions } from "../databaseType/databaseType.type.js";
3
+ /**
4
+ * Supported row lock modes (PostgreSQL).
5
+ */
6
+ export type DatabaseLockMode = "for-update" | "for-no-key-update" | "for-share" | "for-key-share";
7
+ /**
8
+ * Options for acquiring a database lock.
9
+ *
10
+ * All locking in this module is PostgreSQL-specific (`pg_advisory_xact_lock`,
11
+ * `FOR UPDATE ... SKIP LOCKED`, `lock_timeout`).
12
+ */
13
+ export interface DatabaseLockOptions {
14
+ /**
15
+ * Row lock mode. Ignored for advisory locks.
16
+ */
17
+ readonly mode?: DatabaseLockMode;
18
+ /**
19
+ * Maximum time to wait for the lock. Applied with
20
+ * `SET LOCAL lock_timeout` inside the transaction, so a contended lock
21
+ * fails with a lock-timeout error instead of Prisma's generic
22
+ * transaction timeout. When it exceeds Prisma's 5 s default and
23
+ * `transaction.timeoutMs` is not set, the transaction timeout is raised
24
+ * automatically (see `resolveLockTransactionOptions`).
25
+ */
26
+ readonly timeoutMs?: number;
27
+ /**
28
+ * Row locks only: skip rows locked by other transactions instead of
29
+ * waiting. When the row is skipped the lock is *not* held and
30
+ * `acquired` is `false`.
31
+ */
32
+ readonly skipLocked?: boolean;
33
+ /**
34
+ * Fail immediately when the lock is held by another transaction.
35
+ */
36
+ readonly noWait?: boolean;
37
+ /**
38
+ * Advisory locks only: optional namespace. When supplied the two-int
39
+ * form `pg_advisory_xact_lock(int, int)` is used with the namespace
40
+ * hashed into the first argument, so unrelated services sharing one
41
+ * database cannot collide on the same 64-bit key space.
42
+ */
43
+ readonly namespace?: string;
44
+ /**
45
+ * Options forwarded to the transaction opened by the lock manager.
46
+ */
47
+ readonly transaction?: TransactionOptions;
48
+ }
49
+ /**
50
+ * Result of a lock acquisition.
51
+ */
52
+ export interface DatabaseLockResult {
53
+ readonly acquired: boolean;
54
+ readonly lockKey: string;
55
+ readonly mode?: DatabaseLockMode;
56
+ }
57
+ /**
58
+ * Application-level lock abstraction for PostgreSQL.
59
+ *
60
+ * Locks are acquired inside a transaction and released when it ends.
61
+ */
62
+ export declare class DatabaseLockManager {
63
+ private readonly client;
64
+ constructor(client: DatabaseClient);
65
+ /**
66
+ * Executes work inside a transaction after acquiring a PostgreSQL
67
+ * advisory transaction lock.
68
+ */
69
+ withAdvisoryLock<TResult>(lockKey: string, callback: (transaction: DatabaseTransactionContext) => Promise<TResult>, options?: DatabaseLockOptions): Promise<TResult>;
70
+ /**
71
+ * Acquires a row-level lock and executes work while holding it.
72
+ *
73
+ * @throws {DatabaseError} when the row does not exist or was skipped
74
+ * because another transaction holds it (`skipLocked`).
75
+ */
76
+ withRowLock<TResult>(tableName: string, id: string | number, callback: (transaction: DatabaseTransactionContext) => Promise<TResult>, options?: DatabaseLockOptions): Promise<TResult>;
77
+ /**
78
+ * Returns the underlying database client.
79
+ */
80
+ getClient(): DatabaseClient;
81
+ }
82
+ /**
83
+ * Creates a lock manager.
84
+ */
85
+ export declare function createLockManager(client: DatabaseClient): DatabaseLockManager;
86
+ /**
87
+ * Acquires a PostgreSQL advisory transaction lock.
88
+ *
89
+ * The lock key is hashed with FNV-1a to a signed 64-bit key (or, with a
90
+ * `namespace`, to a pair of signed 32-bit keys).
91
+ */
92
+ export declare function acquireAdvisoryLock(transaction: DatabaseTransactionContext, lockKey: string, options?: DatabaseLockOptions): Promise<DatabaseLockResult>;
93
+ /**
94
+ * Acquires a row-level PostgreSQL lock.
95
+ *
96
+ * @throws {DatabaseError} when the row does not exist.
97
+ * @returns `acquired: false` only when `skipLocked` skipped a row held by
98
+ * another transaction.
99
+ */
100
+ export declare function lockRow(transaction: DatabaseTransactionContext, tableName: string, id: string | number, options?: DatabaseLockOptions): Promise<DatabaseLockResult>;
101
+ /**
102
+ * Builds a safe PostgreSQL lock clause.
103
+ */
104
+ export declare function buildLockClause(mode: DatabaseLockMode, options?: DatabaseLockOptions): string;
105
+ /**
106
+ * Converts an application lock key into a deterministic signed 64-bit
107
+ * advisory key (FNV-1a 64).
108
+ */
109
+ export declare function normalizeAdvisoryKey(lockKey: string): bigint;
110
+ /**
111
+ * Converts a namespace and key into the two signed 32-bit integers used by
112
+ * the two-argument advisory lock functions.
113
+ */
114
+ export declare function normalizeAdvisoryKeyPair(namespace: string, lockKey: string): readonly [number, number];
115
+ /**
116
+ * Derives the transaction options for a lock so that `lock_timeout` is
117
+ * always shorter than the surrounding Prisma transaction timeout.
118
+ *
119
+ * Without this, a lock wait longer than Prisma's 5 s default would surface
120
+ * as a generic "transaction already closed" error instead of a lock
121
+ * timeout. When `transaction.timeoutMs` is not supplied it is raised to
122
+ * cover the lock wait plus the default budget for the callback.
123
+ *
124
+ * @throws {TypeError} when `transaction.timeoutMs` is explicitly shorter
125
+ * than `timeoutMs`.
126
+ */
127
+ export declare function resolveLockTransactionOptions(options?: DatabaseLockOptions): TransactionOptions | undefined;
128
+ //# sourceMappingURL=locks.core.d.ts.map