@spfn/core 0.1.0-alpha.88 → 0.2.0-beta.2
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/README.md +1046 -384
- package/dist/boss-D-fGtVgM.d.ts +187 -0
- package/dist/cache/index.d.ts +13 -33
- package/dist/cache/index.js +14 -703
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +167 -17
- package/dist/codegen/index.js +76 -1419
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +1191 -0
- package/dist/config/index.js +264 -0
- package/dist/config/index.js.map +1 -0
- package/dist/db/index.d.ts +728 -59
- package/dist/db/index.js +1028 -1225
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +579 -308
- package/dist/env/index.js +438 -930
- package/dist/env/index.js.map +1 -1
- package/dist/errors/index.d.ts +417 -29
- package/dist/errors/index.js +359 -98
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +108 -0
- package/dist/event/index.js +122 -0
- package/dist/event/index.js.map +1 -0
- package/dist/job/index.d.ts +172 -0
- package/dist/job/index.js +361 -0
- package/dist/job/index.js.map +1 -0
- package/dist/logger/index.d.ts +20 -79
- package/dist/logger/index.js +82 -387
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +2 -11
- package/dist/middleware/index.js +49 -703
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +120 -0
- package/dist/nextjs/index.js +416 -0
- package/dist/nextjs/index.js.map +1 -0
- package/dist/{client/nextjs/index.d.ts → nextjs/server.d.ts} +288 -262
- package/dist/nextjs/server.js +568 -0
- package/dist/nextjs/server.js.map +1 -0
- package/dist/route/index.d.ts +686 -25
- package/dist/route/index.js +440 -1287
- package/dist/route/index.js.map +1 -1
- package/dist/route/types.d.ts +38 -0
- package/dist/route/types.js +3 -0
- package/dist/route/types.js.map +1 -0
- package/dist/server/index.d.ts +201 -67
- package/dist/server/index.js +921 -3182
- package/dist/server/index.js.map +1 -1
- package/dist/types-BGl4QL1w.d.ts +77 -0
- package/dist/types-DRG2XMTR.d.ts +157 -0
- package/package.json +52 -47
- package/dist/auto-loader-JFaZ9gON.d.ts +0 -80
- package/dist/client/index.d.ts +0 -358
- package/dist/client/index.js +0 -357
- package/dist/client/index.js.map +0 -1
- package/dist/client/nextjs/index.js +0 -371
- package/dist/client/nextjs/index.js.map +0 -1
- package/dist/codegen/generators/index.d.ts +0 -19
- package/dist/codegen/generators/index.js +0 -1404
- package/dist/codegen/generators/index.js.map +0 -1
- package/dist/database-errors-BNNmLTJE.d.ts +0 -86
- package/dist/events/index.d.ts +0 -183
- package/dist/events/index.js +0 -77
- package/dist/events/index.js.map +0 -1
- package/dist/index-DHiAqhKv.d.ts +0 -101
- package/dist/index.d.ts +0 -8
- package/dist/index.js +0 -3674
- package/dist/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -121
- package/dist/types/index.js +0 -38
- package/dist/types/index.js.map +0 -1
- package/dist/types-BXibIEyj.d.ts +0 -60
package/dist/db/index.d.ts
CHANGED
|
@@ -4,22 +4,23 @@ import * as drizzle_orm from 'drizzle-orm';
|
|
|
4
4
|
import { SQL } from 'drizzle-orm';
|
|
5
5
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
6
6
|
import { PgColumn, PgTable } from 'drizzle-orm/pg-core';
|
|
7
|
-
import * as
|
|
8
|
-
import {
|
|
7
|
+
import * as hono_types from 'hono/types';
|
|
8
|
+
import { DatabaseError } from '@spfn/core/errors';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Database Configuration
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Database connection and connection pool configuration.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
18
|
-
* -
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* - src/server/core/db/
|
|
15
|
+
* Features:
|
|
16
|
+
* - Environment-specific connection pool configuration
|
|
17
|
+
* - Retry configuration with exponential backoff
|
|
18
|
+
* - Environment variable-based configuration
|
|
19
|
+
* - Health check and monitoring configuration
|
|
20
|
+
*
|
|
21
|
+
* Related files:
|
|
22
|
+
* - src/server/core/db/connection.ts (connection logic)
|
|
23
|
+
* - src/server/core/db/index.ts (main exports)
|
|
23
24
|
*/
|
|
24
25
|
|
|
25
26
|
interface DatabaseClients {
|
|
@@ -71,19 +72,29 @@ interface DatabaseOptions {
|
|
|
71
72
|
monitoring?: Partial<MonitoringConfig>;
|
|
72
73
|
}
|
|
73
74
|
/**
|
|
74
|
-
* Connection
|
|
75
|
+
* Connection pool configuration
|
|
76
|
+
*
|
|
77
|
+
* Controls the maximum number of connections and idle timeout behavior.
|
|
75
78
|
*/
|
|
76
79
|
interface PoolConfig {
|
|
80
|
+
/** Maximum number of connections in the pool */
|
|
77
81
|
max: number;
|
|
82
|
+
/** Idle connection timeout in seconds */
|
|
78
83
|
idleTimeout: number;
|
|
79
84
|
}
|
|
80
85
|
/**
|
|
81
|
-
*
|
|
86
|
+
* Retry configuration for exponential backoff algorithm
|
|
87
|
+
*
|
|
88
|
+
* Controls retry behavior when connection attempts fail.
|
|
82
89
|
*/
|
|
83
90
|
interface RetryConfig {
|
|
91
|
+
/** Maximum number of retry attempts */
|
|
84
92
|
maxRetries: number;
|
|
93
|
+
/** Initial delay between retries in milliseconds */
|
|
85
94
|
initialDelay: number;
|
|
95
|
+
/** Maximum delay cap in milliseconds */
|
|
86
96
|
maxDelay: number;
|
|
97
|
+
/** Exponential backoff factor (delay multiplier) */
|
|
87
98
|
factor: number;
|
|
88
99
|
}
|
|
89
100
|
|
|
@@ -96,12 +107,12 @@ interface RetryConfig {
|
|
|
96
107
|
* Create database client(s) from environment variables
|
|
97
108
|
*
|
|
98
109
|
* Supported patterns (priority order):
|
|
99
|
-
* 1.
|
|
100
|
-
* 2.
|
|
101
|
-
* 3. Legacy replica: DATABASE_URL + DATABASE_REPLICA_URL
|
|
110
|
+
* 1. Primary + Replica: DATABASE_WRITE_URL + DATABASE_READ_URL
|
|
111
|
+
* 2. Single primary: DATABASE_URL
|
|
102
112
|
*
|
|
103
113
|
* @param options - Optional database configuration (pool settings, etc.)
|
|
104
|
-
* @returns Database client(s)
|
|
114
|
+
* @returns Database client(s)
|
|
115
|
+
* @throws {Error} If no database configuration is found or connection fails
|
|
105
116
|
*
|
|
106
117
|
* @example
|
|
107
118
|
* ```bash
|
|
@@ -111,10 +122,6 @@ interface RetryConfig {
|
|
|
111
122
|
* # Primary + Replica
|
|
112
123
|
* DATABASE_WRITE_URL=postgresql://primary:5432/mydb
|
|
113
124
|
* DATABASE_READ_URL=postgresql://replica:5432/mydb
|
|
114
|
-
*
|
|
115
|
-
* # Legacy (backward compatibility)
|
|
116
|
-
* DATABASE_URL=postgresql://primary:5432/mydb
|
|
117
|
-
* DATABASE_REPLICA_URL=postgresql://replica:5432/mydb
|
|
118
125
|
* ```
|
|
119
126
|
*
|
|
120
127
|
* @example
|
|
@@ -128,36 +135,54 @@ interface RetryConfig {
|
|
|
128
135
|
declare function createDatabaseFromEnv(options?: DatabaseOptions): Promise<DatabaseClients>;
|
|
129
136
|
|
|
130
137
|
/**
|
|
131
|
-
*
|
|
132
|
-
* Provides singleton access to database across all modules
|
|
133
|
-
* Supports Primary + Replica pattern with separate read/write instances
|
|
138
|
+
* Database Manager Types
|
|
134
139
|
*/
|
|
135
140
|
|
|
136
141
|
/**
|
|
137
142
|
* DB connection type
|
|
138
143
|
*/
|
|
139
144
|
type DbConnectionType = 'read' | 'write';
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Global Database instance manager
|
|
148
|
+
* Provides singleton access to database across all modules
|
|
149
|
+
* Supports Primary + Replica pattern with separate read/write instances
|
|
150
|
+
*/
|
|
151
|
+
|
|
140
152
|
/**
|
|
141
|
-
* Get global database
|
|
153
|
+
* Get global database instance
|
|
142
154
|
*
|
|
143
|
-
* @
|
|
155
|
+
* @param type - Connection type ('read' or 'write', defaults to 'write')
|
|
156
|
+
* @returns Database instance (never undefined)
|
|
157
|
+
* @throws Error if database is not initialized
|
|
144
158
|
*
|
|
145
159
|
* @example
|
|
146
160
|
* ```typescript
|
|
147
161
|
* import { getDatabase } from '@spfn/core/db';
|
|
148
162
|
*
|
|
163
|
+
* // Always returns a valid instance or throws
|
|
149
164
|
* const db = getDatabase();
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
165
|
+
* const users = await db.select().from(usersTable);
|
|
166
|
+
*
|
|
167
|
+
* // For read operations (uses replica if available, falls back to primary)
|
|
168
|
+
* const dbRead = getDatabase('read');
|
|
169
|
+
* const posts = await dbRead.select().from(postsTable);
|
|
153
170
|
* ```
|
|
154
171
|
*/
|
|
155
|
-
declare function getDatabase(type?: DbConnectionType): PostgresJsDatabase<Record<string, unknown
|
|
172
|
+
declare function getDatabase(type?: DbConnectionType): PostgresJsDatabase<Record<string, unknown>>;
|
|
156
173
|
/**
|
|
157
174
|
* Set global database instances (for testing or manual configuration)
|
|
158
175
|
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
176
|
+
* This function directly sets database instances without creating connections
|
|
177
|
+
* or performing validation. It's primarily intended for testing scenarios.
|
|
178
|
+
*
|
|
179
|
+
* @param write - Database write instance (pass undefined to clear)
|
|
180
|
+
* @param read - Database read instance (optional, defaults to write, pass undefined to clear)
|
|
181
|
+
*
|
|
182
|
+
* @remarks
|
|
183
|
+
* **Important:** To properly close database connections with cleanup, use `closeDatabase()` instead.
|
|
184
|
+
* This function only updates the global instances without closing the underlying connections.
|
|
185
|
+
* Setting both to undefined will clear the instances but leave connections open, which may cause resource leaks.
|
|
161
186
|
*
|
|
162
187
|
* @example
|
|
163
188
|
* ```typescript
|
|
@@ -165,9 +190,13 @@ declare function getDatabase(type?: DbConnectionType): PostgresJsDatabase<Record
|
|
|
165
190
|
* import { drizzle } from 'drizzle-orm/postgres-js';
|
|
166
191
|
* import postgres from 'postgres';
|
|
167
192
|
*
|
|
193
|
+
* // Set custom database instances (testing)
|
|
168
194
|
* const writeClient = postgres('postgresql://primary:5432/mydb');
|
|
169
195
|
* const readClient = postgres('postgresql://replica:5432/mydb');
|
|
170
196
|
* setDatabase(drizzle(writeClient), drizzle(readClient));
|
|
197
|
+
*
|
|
198
|
+
* // Clear instances (not recommended - use closeDatabase() instead)
|
|
199
|
+
* setDatabase(undefined, undefined);
|
|
171
200
|
* ```
|
|
172
201
|
*/
|
|
173
202
|
declare function setDatabase(write: PostgresJsDatabase<Record<string, unknown>> | undefined, read?: PostgresJsDatabase<Record<string, unknown>> | undefined): void;
|
|
@@ -178,7 +207,6 @@ declare function setDatabase(write: PostgresJsDatabase<Record<string, unknown>>
|
|
|
178
207
|
* Supported environment variables:
|
|
179
208
|
* - DATABASE_URL (single primary)
|
|
180
209
|
* - DATABASE_WRITE_URL + DATABASE_READ_URL (primary + replica)
|
|
181
|
-
* - DATABASE_URL + DATABASE_REPLICA_URL (legacy replica)
|
|
182
210
|
* - DB_POOL_MAX (connection pool max size)
|
|
183
211
|
* - DB_POOL_IDLE_TIMEOUT (connection idle timeout in seconds)
|
|
184
212
|
* - DB_HEALTH_CHECK_ENABLED (enable health checks, default: true)
|
|
@@ -247,6 +275,32 @@ declare function initDatabase(options?: DatabaseOptions): Promise<{
|
|
|
247
275
|
declare function closeDatabase(): Promise<void>;
|
|
248
276
|
/**
|
|
249
277
|
* Get database connection info (for debugging)
|
|
278
|
+
*
|
|
279
|
+
* Returns the current state of database connections without throwing errors.
|
|
280
|
+
* Useful for health checks, monitoring, and debugging initialization issues.
|
|
281
|
+
*
|
|
282
|
+
* @returns Connection status information
|
|
283
|
+
* - `hasWrite`: Whether write database instance is initialized
|
|
284
|
+
* - `hasRead`: Whether read database instance is initialized
|
|
285
|
+
* - `isReplica`: Whether read and write are different instances (Primary + Replica setup)
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* import { getDatabaseInfo } from '@spfn/core/db';
|
|
290
|
+
*
|
|
291
|
+
* const info = getDatabaseInfo();
|
|
292
|
+
* console.log(`Write: ${info.hasWrite}, Read: ${info.hasRead}, Replica: ${info.isReplica}`);
|
|
293
|
+
*
|
|
294
|
+
* // Check before using database
|
|
295
|
+
* if (!info.hasWrite) {
|
|
296
|
+
* console.warn('Database not initialized');
|
|
297
|
+
* }
|
|
298
|
+
*
|
|
299
|
+
* // Detect Primary + Replica setup
|
|
300
|
+
* if (info.isReplica) {
|
|
301
|
+
* console.log('Using Primary + Replica configuration');
|
|
302
|
+
* }
|
|
303
|
+
* ```
|
|
250
304
|
*/
|
|
251
305
|
declare function getDatabaseInfo(): {
|
|
252
306
|
hasWrite: boolean;
|
|
@@ -255,19 +309,49 @@ declare function getDatabaseInfo(): {
|
|
|
255
309
|
};
|
|
256
310
|
|
|
257
311
|
/**
|
|
258
|
-
*
|
|
312
|
+
* Create database connection with exponential backoff retry strategy
|
|
313
|
+
*
|
|
314
|
+
* Attempts to establish a database connection with automatic retries using
|
|
315
|
+
* exponential backoff with jitter. Non-retryable errors (authentication,
|
|
316
|
+
* database not found, SSL issues) fail immediately.
|
|
317
|
+
*
|
|
318
|
+
* Retry Strategy:
|
|
319
|
+
* - Exponential backoff: delay = initialDelay * (factor ^ attempt)
|
|
320
|
+
* - Jitter: randomized delay between 50-100% of calculated delay
|
|
321
|
+
* - Max delay cap: prevents excessive wait times
|
|
259
322
|
*
|
|
260
|
-
* @param connectionString - PostgreSQL
|
|
261
|
-
* @param poolConfig - Connection
|
|
262
|
-
* @param retryConfig -
|
|
263
|
-
* @returns PostgreSQL
|
|
323
|
+
* @param connectionString - PostgreSQL connection string
|
|
324
|
+
* @param poolConfig - Connection pool configuration
|
|
325
|
+
* @param retryConfig - Retry configuration (max attempts, delays, etc.)
|
|
326
|
+
* @returns PostgreSQL client instance
|
|
327
|
+
* @throws ConnectionError if connection fails after all retries or on non-retryable errors
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* const client = await createDatabaseConnection(
|
|
332
|
+
* 'postgresql://localhost:5432/mydb',
|
|
333
|
+
* { max: 20, idleTimeout: 30 },
|
|
334
|
+
* { maxRetries: 5, initialDelay: 100, maxDelay: 10000, factor: 2 }
|
|
335
|
+
* );
|
|
336
|
+
* ```
|
|
264
337
|
*/
|
|
265
338
|
declare function createDatabaseConnection(connectionString: string, poolConfig: PoolConfig, retryConfig: RetryConfig): Promise<postgres.Sql<{}>>;
|
|
266
339
|
/**
|
|
267
|
-
*
|
|
340
|
+
* Check database connection health
|
|
341
|
+
*
|
|
342
|
+
* Uses the client's configured timeout settings (connect_timeout, etc.).
|
|
343
|
+
* Executes a simple SELECT query to verify the connection is alive.
|
|
268
344
|
*
|
|
269
|
-
* @param client - PostgreSQL
|
|
270
|
-
* @returns
|
|
345
|
+
* @param client - PostgreSQL client to check
|
|
346
|
+
* @returns true if connection is healthy, false otherwise
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const isHealthy = await checkConnection(client);
|
|
351
|
+
* if (!isHealthy) {
|
|
352
|
+
* console.error('Database connection is down');
|
|
353
|
+
* }
|
|
354
|
+
* ```
|
|
271
355
|
*/
|
|
272
356
|
declare function checkConnection(client: Sql): Promise<boolean>;
|
|
273
357
|
|
|
@@ -290,6 +374,8 @@ interface DrizzleConfigOptions {
|
|
|
290
374
|
disablePackageDiscovery?: boolean;
|
|
291
375
|
/** Only include schemas from specific package (e.g., '@spfn/cms') */
|
|
292
376
|
packageFilter?: string;
|
|
377
|
+
/** Expand glob patterns to actual file paths (useful for Drizzle Studio) */
|
|
378
|
+
expandGlobs?: boolean;
|
|
293
379
|
}
|
|
294
380
|
/**
|
|
295
381
|
* Detect database dialect from connection URL
|
|
@@ -348,32 +434,28 @@ declare function id(): drizzle_orm.IsPrimaryKey<drizzle_orm.NotNull<drizzle_orm_
|
|
|
348
434
|
* Standard timestamp fields (createdAt, updatedAt)
|
|
349
435
|
*
|
|
350
436
|
* Both fields are timezone-aware, auto-set to current time on creation.
|
|
351
|
-
*
|
|
437
|
+
* updatedAt must be manually updated in your application code.
|
|
352
438
|
*
|
|
353
|
-
* @param options - Optional configuration
|
|
354
|
-
* @param options.autoUpdate - Automatically update updatedAt on record updates (default: false)
|
|
355
439
|
* @returns Object with createdAt and updatedAt columns
|
|
356
440
|
*
|
|
357
441
|
* @example
|
|
358
442
|
* ```typescript
|
|
359
|
-
* // Without auto-update
|
|
360
443
|
* export const users = pgTable('users', {
|
|
361
444
|
* id: id(),
|
|
362
445
|
* email: text('email'),
|
|
363
446
|
* ...timestamps(),
|
|
364
447
|
* });
|
|
365
448
|
*
|
|
366
|
-
* //
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
449
|
+
* // Manual update
|
|
450
|
+
* await db.update(users)
|
|
451
|
+
* .set({
|
|
452
|
+
* email: 'new@example.com',
|
|
453
|
+
* updatedAt: new Date()
|
|
454
|
+
* })
|
|
455
|
+
* .where(eq(users.id, userId));
|
|
372
456
|
* ```
|
|
373
457
|
*/
|
|
374
|
-
declare function timestamps(
|
|
375
|
-
autoUpdate?: boolean;
|
|
376
|
-
}): {
|
|
458
|
+
declare function timestamps(): {
|
|
377
459
|
createdAt: drizzle_orm.NotNull<drizzle_orm.HasDefault<drizzle_orm_pg_core.PgTimestampBuilderInitial<"created_at">>>;
|
|
378
460
|
updatedAt: drizzle_orm.NotNull<drizzle_orm.HasDefault<drizzle_orm_pg_core.PgTimestampBuilderInitial<"updated_at">>>;
|
|
379
461
|
};
|
|
@@ -421,6 +503,256 @@ declare function foreignKey<T extends PgColumn>(name: string, reference: () => T
|
|
|
421
503
|
declare function optionalForeignKey<T extends PgColumn>(name: string, reference: () => T, options?: {
|
|
422
504
|
onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
423
505
|
}): drizzle_orm_pg_core.PgBigSerial53BuilderInitial<`${string}_id`>;
|
|
506
|
+
/**
|
|
507
|
+
* UUID primary key
|
|
508
|
+
*
|
|
509
|
+
* Creates a UUID column as primary key with automatic default value generation.
|
|
510
|
+
* Useful for distributed systems or when you need globally unique identifiers.
|
|
511
|
+
*
|
|
512
|
+
* @returns uuid primary key column with gen_random_uuid() default
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* export const sessions = pgTable('sessions', {
|
|
517
|
+
* id: uuid(),
|
|
518
|
+
* userId: foreignKey('user', () => users.id),
|
|
519
|
+
* ...timestamps(),
|
|
520
|
+
* });
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
declare function uuid(): drizzle_orm.IsPrimaryKey<drizzle_orm.NotNull<drizzle_orm.HasDefault<drizzle_orm_pg_core.PgUUIDBuilderInitial<"id">>>>;
|
|
524
|
+
/**
|
|
525
|
+
* Audit fields for tracking record creators and updaters
|
|
526
|
+
*
|
|
527
|
+
* Adds createdBy and updatedBy fields for user tracking.
|
|
528
|
+
* Typically stores user IDs, emails, or usernames.
|
|
529
|
+
*
|
|
530
|
+
* @returns Object with createdBy and updatedBy columns
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```typescript
|
|
534
|
+
* export const posts = pgTable('posts', {
|
|
535
|
+
* id: id(),
|
|
536
|
+
* title: text('title'),
|
|
537
|
+
* ...timestamps(),
|
|
538
|
+
* ...auditFields(),
|
|
539
|
+
* });
|
|
540
|
+
*
|
|
541
|
+
* // Usage in route
|
|
542
|
+
* await db.insert(posts).values({
|
|
543
|
+
* title: 'New Post',
|
|
544
|
+
* createdBy: currentUser.email,
|
|
545
|
+
* });
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function auditFields(): {
|
|
549
|
+
createdBy: drizzle_orm_pg_core.PgTextBuilderInitial<"created_by", [string, ...string[]]>;
|
|
550
|
+
updatedBy: drizzle_orm_pg_core.PgTextBuilderInitial<"updated_by", [string, ...string[]]>;
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* Publishing fields for content management
|
|
554
|
+
*
|
|
555
|
+
* Tracks when and by whom content was published.
|
|
556
|
+
* Useful for CMS, blog posts, articles, etc.
|
|
557
|
+
*
|
|
558
|
+
* @returns Object with publishedAt and publishedBy columns
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* ```typescript
|
|
562
|
+
* export const articles = pgTable('articles', {
|
|
563
|
+
* id: id(),
|
|
564
|
+
* title: text('title'),
|
|
565
|
+
* status: text('status'), // draft/published/archived
|
|
566
|
+
* ...publishingFields(),
|
|
567
|
+
* ...timestamps(),
|
|
568
|
+
* });
|
|
569
|
+
*
|
|
570
|
+
* // Publishing an article
|
|
571
|
+
* await db.update(articles)
|
|
572
|
+
* .set({
|
|
573
|
+
* status: 'published',
|
|
574
|
+
* publishedAt: new Date(),
|
|
575
|
+
* publishedBy: currentUser.email,
|
|
576
|
+
* })
|
|
577
|
+
* .where(eq(articles.id, articleId));
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
declare function publishingFields(): {
|
|
581
|
+
publishedAt: drizzle_orm_pg_core.PgTimestampBuilderInitial<"published_at">;
|
|
582
|
+
publishedBy: drizzle_orm_pg_core.PgTextBuilderInitial<"published_by", [string, ...string[]]>;
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Custom verification timestamp field
|
|
586
|
+
*
|
|
587
|
+
* Creates a nullable timestamp field for tracking verification status.
|
|
588
|
+
* Useful for email verification, phone verification, etc.
|
|
589
|
+
*
|
|
590
|
+
* @param fieldName - Field name in camelCase (e.g., 'emailVerified', 'phoneVerified')
|
|
591
|
+
* @returns Object with verification timestamp column (converts to snake_case + '_at')
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```typescript
|
|
595
|
+
* export const users = pgTable('users', {
|
|
596
|
+
* id: id(),
|
|
597
|
+
* email: text('email'),
|
|
598
|
+
* phone: text('phone'),
|
|
599
|
+
* ...verificationTimestamp('emailVerified'), // emailVerifiedAt -> email_verified_at
|
|
600
|
+
* ...verificationTimestamp('phoneVerified'), // phoneVerifiedAt -> phone_verified_at
|
|
601
|
+
* ...timestamps(),
|
|
602
|
+
* });
|
|
603
|
+
*
|
|
604
|
+
* // Verify email
|
|
605
|
+
* await db.update(users)
|
|
606
|
+
* .set({ emailVerifiedAt: new Date() })
|
|
607
|
+
* .where(eq(users.email, userEmail));
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
declare function verificationTimestamp(fieldName: string): {
|
|
611
|
+
[x: string]: drizzle_orm_pg_core.PgTimestampBuilderInitial<string>;
|
|
612
|
+
};
|
|
613
|
+
/**
|
|
614
|
+
* Soft delete fields
|
|
615
|
+
*
|
|
616
|
+
* Adds deletedAt and deletedBy for logical deletion.
|
|
617
|
+
* Records are marked as deleted instead of being physically removed.
|
|
618
|
+
*
|
|
619
|
+
* @returns Object with deletedAt and deletedBy columns
|
|
620
|
+
*
|
|
621
|
+
* @example
|
|
622
|
+
* ```typescript
|
|
623
|
+
* export const posts = pgTable('posts', {
|
|
624
|
+
* id: id(),
|
|
625
|
+
* title: text('title'),
|
|
626
|
+
* ...timestamps(),
|
|
627
|
+
* ...softDelete(),
|
|
628
|
+
* });
|
|
629
|
+
*
|
|
630
|
+
* // Soft delete
|
|
631
|
+
* await db.update(posts)
|
|
632
|
+
* .set({
|
|
633
|
+
* deletedAt: new Date(),
|
|
634
|
+
* deletedBy: currentUser.email,
|
|
635
|
+
* })
|
|
636
|
+
* .where(eq(posts.id, postId));
|
|
637
|
+
*
|
|
638
|
+
* // Query only non-deleted records
|
|
639
|
+
* const activePosts = await db.select()
|
|
640
|
+
* .from(posts)
|
|
641
|
+
* .where(isNull(posts.deletedAt));
|
|
642
|
+
* ```
|
|
643
|
+
*/
|
|
644
|
+
declare function softDelete(): {
|
|
645
|
+
deletedAt: drizzle_orm_pg_core.PgTimestampBuilderInitial<"deleted_at">;
|
|
646
|
+
deletedBy: drizzle_orm_pg_core.PgTextBuilderInitial<"deleted_by", [string, ...string[]]>;
|
|
647
|
+
};
|
|
648
|
+
/**
|
|
649
|
+
* UTC timestamp field
|
|
650
|
+
*
|
|
651
|
+
* Creates a timezone-aware timestamp column (TIMESTAMPTZ) that stores values in UTC.
|
|
652
|
+
* PostgreSQL automatically converts between client timezone and UTC.
|
|
653
|
+
* Chain with .notNull(), .defaultNow(), etc. for additional constraints.
|
|
654
|
+
*
|
|
655
|
+
* @param fieldName - Database column name (in snake_case)
|
|
656
|
+
* @param mode - Data type mode: 'date' (Date object) or 'string' (ISO string)
|
|
657
|
+
* @returns Timestamp column with timezone support
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```typescript
|
|
661
|
+
* export const users = pgTable('users', {
|
|
662
|
+
* id: id(),
|
|
663
|
+
* email: text('email'),
|
|
664
|
+
*
|
|
665
|
+
* // Nullable timestamp
|
|
666
|
+
* emailVerifiedAt: utcTimestamp('email_verified_at'),
|
|
667
|
+
*
|
|
668
|
+
* // Required with default
|
|
669
|
+
* lastLoginAt: utcTimestamp('last_login_at').defaultNow().notNull(),
|
|
670
|
+
*
|
|
671
|
+
* // String mode
|
|
672
|
+
* processedAt: utcTimestamp('processed_at', 'string'),
|
|
673
|
+
*
|
|
674
|
+
* ...timestamps(),
|
|
675
|
+
* });
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
declare function utcTimestamp(fieldName: string, mode?: 'date' | 'string'): drizzle_orm_pg_core.PgTimestampBuilderInitial<string>;
|
|
679
|
+
/**
|
|
680
|
+
* Type-safe enum text field
|
|
681
|
+
*
|
|
682
|
+
* Creates a text column with enum constraint.
|
|
683
|
+
* Chain with .notNull(), .default(), etc. for additional constraints.
|
|
684
|
+
*
|
|
685
|
+
* @param fieldName - Database column name (e.g., 'status', 'role', 'provider')
|
|
686
|
+
* @param values - Const array of allowed values
|
|
687
|
+
* @returns Text column with enum constraint
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* ```typescript
|
|
691
|
+
* export const USER_STATUSES = ['active', 'inactive', 'suspended'] as const;
|
|
692
|
+
* export type UserStatus = typeof USER_STATUSES[number];
|
|
693
|
+
*
|
|
694
|
+
* export const SOCIAL_PROVIDERS = ['google', 'github', 'kakao'] as const;
|
|
695
|
+
* export type SocialProvider = typeof SOCIAL_PROVIDERS[number];
|
|
696
|
+
*
|
|
697
|
+
* export const users = pgTable('users', {
|
|
698
|
+
* id: id(),
|
|
699
|
+
* // Nullable
|
|
700
|
+
* role: enumText('role', USER_STATUSES),
|
|
701
|
+
*
|
|
702
|
+
* // Required
|
|
703
|
+
* provider: enumText('provider', SOCIAL_PROVIDERS).notNull(),
|
|
704
|
+
*
|
|
705
|
+
* // Required with default
|
|
706
|
+
* status: enumText('status', USER_STATUSES).default('active').notNull(),
|
|
707
|
+
*
|
|
708
|
+
* ...timestamps(),
|
|
709
|
+
* });
|
|
710
|
+
* ```
|
|
711
|
+
*/
|
|
712
|
+
declare function enumText<T extends readonly [string, ...string[]]>(fieldName: string, values: T): drizzle_orm_pg_core.PgTextBuilderInitial<string, drizzle_orm.Writable<T & [string, ...string[]]>>;
|
|
713
|
+
/**
|
|
714
|
+
* Type-safe JSONB field
|
|
715
|
+
*
|
|
716
|
+
* Creates a JSONB column with required type parameter to ensure type safety.
|
|
717
|
+
* Prevents the common mistake of using jsonb without type annotation,
|
|
718
|
+
* which would result in `unknown` type and require type assertions.
|
|
719
|
+
*
|
|
720
|
+
* Chain with .notNull(), .default(), etc. for additional constraints.
|
|
721
|
+
*
|
|
722
|
+
* @param fieldName - Database column name (in snake_case)
|
|
723
|
+
* @returns JSONB column with specified type
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```typescript
|
|
727
|
+
* // Define your types
|
|
728
|
+
* type LabelValue =
|
|
729
|
+
* | { type: 'text'; content: string }
|
|
730
|
+
* | { type: 'image'; url: string; alt?: string };
|
|
731
|
+
*
|
|
732
|
+
* type CachedContent = Record<string, LabelValue>;
|
|
733
|
+
*
|
|
734
|
+
* export const cmsPublishedCache = pgTable('published_cache', {
|
|
735
|
+
* id: id(),
|
|
736
|
+
* section: text('section').notNull(),
|
|
737
|
+
*
|
|
738
|
+
* // Type-safe JSONB field - no more `as any` needed!
|
|
739
|
+
* content: typedJsonb<CachedContent>('content').notNull(),
|
|
740
|
+
*
|
|
741
|
+
* ...timestamps(),
|
|
742
|
+
* });
|
|
743
|
+
*
|
|
744
|
+
* // Usage in route - no type assertion needed
|
|
745
|
+
* const cache = await db.select().from(cmsPublishedCache)...;
|
|
746
|
+
* const labels = cache.content; // Type: CachedContent ✅
|
|
747
|
+
*
|
|
748
|
+
* // For simple objects
|
|
749
|
+
* metadata: typedJsonb<Record<string, any>>('metadata'),
|
|
750
|
+
*
|
|
751
|
+
* // For arrays
|
|
752
|
+
* tags: typedJsonb<string[]>('tags').notNull(),
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
755
|
+
declare function typedJsonb<T>(fieldName: string): drizzle_orm.$Type<drizzle_orm_pg_core.PgJsonbBuilderInitial<string>, T>;
|
|
424
756
|
|
|
425
757
|
/**
|
|
426
758
|
* Database Schema Helper
|
|
@@ -436,9 +768,9 @@ declare function optionalForeignKey<T extends PgColumn>(name: string, reference:
|
|
|
436
768
|
* @example
|
|
437
769
|
* ```typescript
|
|
438
770
|
* // @spfn/cms → spfn_cms schema
|
|
439
|
-
* import {
|
|
771
|
+
* import { createSchema } from '@spfn/core/db';
|
|
440
772
|
*
|
|
441
|
-
* const schema =
|
|
773
|
+
* const schema = createSchema('@spfn/cms');
|
|
442
774
|
*
|
|
443
775
|
* export const labels = schema.table('labels', {
|
|
444
776
|
* id: id(),
|
|
@@ -447,7 +779,7 @@ declare function optionalForeignKey<T extends PgColumn>(name: string, reference:
|
|
|
447
779
|
* // Creates table: spfn_cms.labels
|
|
448
780
|
* ```
|
|
449
781
|
*/
|
|
450
|
-
declare function
|
|
782
|
+
declare function createSchema(packageName: string): drizzle_orm_pg_core.PgSchema<string>;
|
|
451
783
|
/**
|
|
452
784
|
* Convert package name to PostgreSQL schema name
|
|
453
785
|
*
|
|
@@ -608,7 +940,7 @@ interface TransactionalOptions {
|
|
|
608
940
|
* - Measures and records execution time
|
|
609
941
|
* - Warns about slow transactions (default: > 1s)
|
|
610
942
|
*/
|
|
611
|
-
declare function Transactional(options?: TransactionalOptions):
|
|
943
|
+
declare function Transactional(options?: TransactionalOptions): hono_types.MiddlewareHandler<any, string, {}, Response>;
|
|
612
944
|
|
|
613
945
|
/**
|
|
614
946
|
* PostgreSQL Error Conversion Utilities
|
|
@@ -881,4 +1213,341 @@ declare function deleteMany<T extends PgTable>(table: T, where: WhereObject<Infe
|
|
|
881
1213
|
*/
|
|
882
1214
|
declare function count<T extends PgTable>(table: T, where?: WhereObject<InferSelectModel<T>> | SQL | undefined): Promise<number>;
|
|
883
1215
|
|
|
884
|
-
|
|
1216
|
+
/**
|
|
1217
|
+
* Base Repository Pattern
|
|
1218
|
+
*
|
|
1219
|
+
* Provides automatic database instance management with transaction context support.
|
|
1220
|
+
* Eliminates the need for manual `getDatabaseOrThrow()` calls in repository classes.
|
|
1221
|
+
*
|
|
1222
|
+
* Features:
|
|
1223
|
+
* - Automatic transaction context detection and usage
|
|
1224
|
+
* - Read/Write connection separation (with replica support)
|
|
1225
|
+
* - Type-safe schema generics
|
|
1226
|
+
* - Consistent database access pattern across all repositories
|
|
1227
|
+
* - Enhanced error tracking with repository context
|
|
1228
|
+
*
|
|
1229
|
+
* @example Basic Repository
|
|
1230
|
+
* ```typescript
|
|
1231
|
+
* import { BaseRepository } from '@spfn/core/db';
|
|
1232
|
+
* import { users } from './schema';
|
|
1233
|
+
* import { eq } from 'drizzle-orm';
|
|
1234
|
+
*
|
|
1235
|
+
* export class UserRepository extends BaseRepository {
|
|
1236
|
+
* async findById(id: string) {
|
|
1237
|
+
* // Uses read replica when available
|
|
1238
|
+
* return await this.readDb
|
|
1239
|
+
* .select()
|
|
1240
|
+
* .from(users)
|
|
1241
|
+
* .where(eq(users.id, id));
|
|
1242
|
+
* }
|
|
1243
|
+
*
|
|
1244
|
+
* async create(data: NewUser) {
|
|
1245
|
+
* // Uses write primary
|
|
1246
|
+
* return await this.db
|
|
1247
|
+
* .insert(users)
|
|
1248
|
+
* .values(data)
|
|
1249
|
+
* .returning();
|
|
1250
|
+
* }
|
|
1251
|
+
* }
|
|
1252
|
+
* ```
|
|
1253
|
+
*
|
|
1254
|
+
* @example With Transactions
|
|
1255
|
+
* ```typescript
|
|
1256
|
+
* import { runWithTransaction } from '@spfn/core/db';
|
|
1257
|
+
*
|
|
1258
|
+
* const userRepo = new UserRepository();
|
|
1259
|
+
*
|
|
1260
|
+
* await runWithTransaction(async () => {
|
|
1261
|
+
* // Both db and readDb automatically use the transaction context
|
|
1262
|
+
* const user = await userRepo.create({ name: 'John' });
|
|
1263
|
+
* await userRepo.findById(user.id); // Uses same transaction
|
|
1264
|
+
* });
|
|
1265
|
+
* ```
|
|
1266
|
+
*
|
|
1267
|
+
* @example With Custom Schema Type
|
|
1268
|
+
* ```typescript
|
|
1269
|
+
* import type { AppSchema } from './schema';
|
|
1270
|
+
*
|
|
1271
|
+
* export class UserRepository extends BaseRepository<AppSchema> {
|
|
1272
|
+
* // Now this.db and this.readDb are typed with AppSchema
|
|
1273
|
+
* }
|
|
1274
|
+
* ```
|
|
1275
|
+
*
|
|
1276
|
+
* @example With Enhanced Error Tracking
|
|
1277
|
+
* ```typescript
|
|
1278
|
+
* export class UserRepository extends BaseRepository {
|
|
1279
|
+
* async updateStatus(id: string, status: string) {
|
|
1280
|
+
* // Errors will include repository context automatically
|
|
1281
|
+
* return await this.db
|
|
1282
|
+
* .update(users)
|
|
1283
|
+
* .set({ status })
|
|
1284
|
+
* .where(eq(users.id, id))
|
|
1285
|
+
* .returning();
|
|
1286
|
+
* }
|
|
1287
|
+
* }
|
|
1288
|
+
* // On error: logs will show "UserRepository" context
|
|
1289
|
+
* ```
|
|
1290
|
+
*/
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* Enhanced error class that includes repository context
|
|
1294
|
+
*/
|
|
1295
|
+
declare class RepositoryError extends Error {
|
|
1296
|
+
readonly repository: string;
|
|
1297
|
+
readonly method?: string | undefined;
|
|
1298
|
+
readonly table?: string | undefined;
|
|
1299
|
+
readonly originalError?: Error | undefined;
|
|
1300
|
+
constructor(message: string, repository: string, method?: string | undefined, table?: string | undefined, originalError?: Error | undefined);
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Base Repository class for database operations
|
|
1304
|
+
*
|
|
1305
|
+
* Provides automatic database instance management with transaction support.
|
|
1306
|
+
* Extend this class to create domain-specific repositories.
|
|
1307
|
+
*
|
|
1308
|
+
* The repository automatically detects if running within a transaction context
|
|
1309
|
+
* and uses the appropriate database instance:
|
|
1310
|
+
* - Inside transaction: Uses transaction DB
|
|
1311
|
+
* - Outside transaction: Uses global DB instance (with read/write separation)
|
|
1312
|
+
*
|
|
1313
|
+
* @template TSchema - Database schema type (defaults to Record<string, unknown>)
|
|
1314
|
+
*/
|
|
1315
|
+
declare abstract class BaseRepository<TSchema extends Record<string, unknown> = Record<string, unknown>> {
|
|
1316
|
+
/**
|
|
1317
|
+
* Write database instance
|
|
1318
|
+
*
|
|
1319
|
+
* Automatically resolves to:
|
|
1320
|
+
* - Transaction DB if running within transaction context
|
|
1321
|
+
* - Global write (primary) instance otherwise
|
|
1322
|
+
*
|
|
1323
|
+
* Use this for INSERT, UPDATE, DELETE operations.
|
|
1324
|
+
*
|
|
1325
|
+
* @example
|
|
1326
|
+
* ```typescript
|
|
1327
|
+
* async create(data: NewUser) {
|
|
1328
|
+
* return await this.db.insert(users).values(data).returning();
|
|
1329
|
+
* }
|
|
1330
|
+
* ```
|
|
1331
|
+
*/
|
|
1332
|
+
protected get db(): PostgresJsDatabase<TSchema>;
|
|
1333
|
+
/**
|
|
1334
|
+
* Read database instance
|
|
1335
|
+
*
|
|
1336
|
+
* Automatically resolves to:
|
|
1337
|
+
* - Transaction DB if running within transaction context
|
|
1338
|
+
* - Global read (replica) instance otherwise
|
|
1339
|
+
*
|
|
1340
|
+
* Use this for SELECT operations to leverage read replicas
|
|
1341
|
+
* and reduce load on the primary database.
|
|
1342
|
+
*
|
|
1343
|
+
* @example
|
|
1344
|
+
* ```typescript
|
|
1345
|
+
* async findById(id: string) {
|
|
1346
|
+
* return await this.readDb
|
|
1347
|
+
* .select()
|
|
1348
|
+
* .from(users)
|
|
1349
|
+
* .where(eq(users.id, id));
|
|
1350
|
+
* }
|
|
1351
|
+
* ```
|
|
1352
|
+
*/
|
|
1353
|
+
protected get readDb(): PostgresJsDatabase<TSchema>;
|
|
1354
|
+
/**
|
|
1355
|
+
* Wrap query execution with repository context
|
|
1356
|
+
*
|
|
1357
|
+
* Enhances error messages with repository information to make debugging easier.
|
|
1358
|
+
* When an error occurs, it will include:
|
|
1359
|
+
* - Repository class name
|
|
1360
|
+
* - Method name
|
|
1361
|
+
* - Table name (if provided)
|
|
1362
|
+
* - Original error details
|
|
1363
|
+
*
|
|
1364
|
+
* @param queryFn - Query function to execute
|
|
1365
|
+
* @param context - Context information (operation name, table name, etc.)
|
|
1366
|
+
* @returns Query result
|
|
1367
|
+
* @throws RepositoryError with enhanced context
|
|
1368
|
+
*
|
|
1369
|
+
* @example
|
|
1370
|
+
* ```typescript
|
|
1371
|
+
* async findById(id: number) {
|
|
1372
|
+
* return await this.withContext(
|
|
1373
|
+
* () => this.readDb.select().from(users).where(eq(users.id, id)),
|
|
1374
|
+
* { method: 'findById', table: 'users' }
|
|
1375
|
+
* );
|
|
1376
|
+
* }
|
|
1377
|
+
* ```
|
|
1378
|
+
*/
|
|
1379
|
+
protected withContext<T>(queryFn: () => Promise<T>, context?: {
|
|
1380
|
+
method?: string;
|
|
1381
|
+
table?: string;
|
|
1382
|
+
}): Promise<T>;
|
|
1383
|
+
/**
|
|
1384
|
+
* Find a single record
|
|
1385
|
+
*
|
|
1386
|
+
* @param table - Drizzle table schema
|
|
1387
|
+
* @param where - Object or SQL condition
|
|
1388
|
+
* @returns Single record or null
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```typescript
|
|
1392
|
+
* // Object-based
|
|
1393
|
+
* const user = await this._findOne(users, { id: 1 });
|
|
1394
|
+
*
|
|
1395
|
+
* // SQL-based
|
|
1396
|
+
* const user = await this._findOne(users, eq(users.id, 1));
|
|
1397
|
+
* ```
|
|
1398
|
+
*/
|
|
1399
|
+
protected _findOne<T extends PgTable>(table: T, where: Record<string, any> | SQL | undefined): Promise<T['$inferSelect'] | null>;
|
|
1400
|
+
/**
|
|
1401
|
+
* Find multiple records
|
|
1402
|
+
*
|
|
1403
|
+
* @param table - Drizzle table schema
|
|
1404
|
+
* @param options - Query options
|
|
1405
|
+
* @returns Array of records
|
|
1406
|
+
*
|
|
1407
|
+
* @example
|
|
1408
|
+
* ```typescript
|
|
1409
|
+
* const users = await this._findMany(users, {
|
|
1410
|
+
* where: { active: true },
|
|
1411
|
+
* orderBy: desc(users.createdAt),
|
|
1412
|
+
* limit: 10
|
|
1413
|
+
* });
|
|
1414
|
+
* ```
|
|
1415
|
+
*/
|
|
1416
|
+
protected _findMany<T extends PgTable>(table: T, options?: {
|
|
1417
|
+
where?: Record<string, any> | SQL | undefined;
|
|
1418
|
+
orderBy?: SQL | SQL[];
|
|
1419
|
+
limit?: number;
|
|
1420
|
+
offset?: number;
|
|
1421
|
+
}): Promise<T['$inferSelect'][]>;
|
|
1422
|
+
/**
|
|
1423
|
+
* Create a new record
|
|
1424
|
+
*
|
|
1425
|
+
* @param table - Drizzle table schema
|
|
1426
|
+
* @param data - Insert data
|
|
1427
|
+
* @returns Created record
|
|
1428
|
+
*
|
|
1429
|
+
* @example
|
|
1430
|
+
* ```typescript
|
|
1431
|
+
* const user = await this._create(users, {
|
|
1432
|
+
* email: 'test@example.com',
|
|
1433
|
+
* name: 'Test User'
|
|
1434
|
+
* });
|
|
1435
|
+
* ```
|
|
1436
|
+
*/
|
|
1437
|
+
protected _create<T extends PgTable>(table: T, data: T['$inferInsert']): Promise<T['$inferSelect']>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Create multiple records
|
|
1440
|
+
*
|
|
1441
|
+
* @param table - Drizzle table schema
|
|
1442
|
+
* @param data - Array of insert data
|
|
1443
|
+
* @returns Array of created records
|
|
1444
|
+
*
|
|
1445
|
+
* @example
|
|
1446
|
+
* ```typescript
|
|
1447
|
+
* const users = await this._createMany(users, [
|
|
1448
|
+
* { email: 'user1@example.com', name: 'User 1' },
|
|
1449
|
+
* { email: 'user2@example.com', name: 'User 2' }
|
|
1450
|
+
* ]);
|
|
1451
|
+
* ```
|
|
1452
|
+
*/
|
|
1453
|
+
protected _createMany<T extends PgTable>(table: T, data: T['$inferInsert'][]): Promise<T['$inferSelect'][]>;
|
|
1454
|
+
/**
|
|
1455
|
+
* Upsert a record (INSERT or UPDATE on conflict)
|
|
1456
|
+
*
|
|
1457
|
+
* @param table - Drizzle table schema
|
|
1458
|
+
* @param data - Insert data
|
|
1459
|
+
* @param options - Conflict resolution options
|
|
1460
|
+
* @returns Upserted record
|
|
1461
|
+
*
|
|
1462
|
+
* @example
|
|
1463
|
+
* ```typescript
|
|
1464
|
+
* const cache = await this._upsert(cache, {
|
|
1465
|
+
* key: 'config',
|
|
1466
|
+
* value: {...}
|
|
1467
|
+
* }, {
|
|
1468
|
+
* target: [cache.key],
|
|
1469
|
+
* set: { value: data.value, updatedAt: new Date() }
|
|
1470
|
+
* });
|
|
1471
|
+
* ```
|
|
1472
|
+
*/
|
|
1473
|
+
protected _upsert<T extends PgTable>(table: T, data: T['$inferInsert'], options: {
|
|
1474
|
+
target: PgColumn[];
|
|
1475
|
+
set?: Partial<T['$inferInsert']> | Record<string, SQL | any>;
|
|
1476
|
+
}): Promise<T['$inferSelect']>;
|
|
1477
|
+
/**
|
|
1478
|
+
* Update a single record
|
|
1479
|
+
*
|
|
1480
|
+
* @param table - Drizzle table schema
|
|
1481
|
+
* @param where - Object or SQL condition
|
|
1482
|
+
* @param data - Update data
|
|
1483
|
+
* @returns Updated record or null
|
|
1484
|
+
*
|
|
1485
|
+
* @example
|
|
1486
|
+
* ```typescript
|
|
1487
|
+
* const user = await this._updateOne(users,
|
|
1488
|
+
* { id: 1 },
|
|
1489
|
+
* { name: 'Updated Name' }
|
|
1490
|
+
* );
|
|
1491
|
+
* ```
|
|
1492
|
+
*/
|
|
1493
|
+
protected _updateOne<T extends PgTable>(table: T, where: Record<string, any> | SQL | undefined, data: Partial<T['$inferInsert']>): Promise<T['$inferSelect'] | null>;
|
|
1494
|
+
/**
|
|
1495
|
+
* Update multiple records
|
|
1496
|
+
*
|
|
1497
|
+
* @param table - Drizzle table schema
|
|
1498
|
+
* @param where - Object or SQL condition
|
|
1499
|
+
* @param data - Update data
|
|
1500
|
+
* @returns Array of updated records
|
|
1501
|
+
*
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```typescript
|
|
1504
|
+
* const users = await this._updateMany(users,
|
|
1505
|
+
* { role: 'user' },
|
|
1506
|
+
* { verified: true }
|
|
1507
|
+
* );
|
|
1508
|
+
* ```
|
|
1509
|
+
*/
|
|
1510
|
+
protected _updateMany<T extends PgTable>(table: T, where: Record<string, any> | SQL | undefined, data: Partial<T['$inferInsert']>): Promise<T['$inferSelect'][]>;
|
|
1511
|
+
/**
|
|
1512
|
+
* Delete a single record
|
|
1513
|
+
*
|
|
1514
|
+
* @param table - Drizzle table schema
|
|
1515
|
+
* @param where - Object or SQL condition
|
|
1516
|
+
* @returns Deleted record or null
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* ```typescript
|
|
1520
|
+
* const user = await this._deleteOne(users, { id: 1 });
|
|
1521
|
+
* ```
|
|
1522
|
+
*/
|
|
1523
|
+
protected _deleteOne<T extends PgTable>(table: T, where: Record<string, any> | SQL | undefined): Promise<T['$inferSelect'] | null>;
|
|
1524
|
+
/**
|
|
1525
|
+
* Delete multiple records
|
|
1526
|
+
*
|
|
1527
|
+
* @param table - Drizzle table schema
|
|
1528
|
+
* @param where - Object or SQL condition
|
|
1529
|
+
* @returns Array of deleted records
|
|
1530
|
+
*
|
|
1531
|
+
* @example
|
|
1532
|
+
* ```typescript
|
|
1533
|
+
* const users = await this._deleteMany(users, { verified: false });
|
|
1534
|
+
* ```
|
|
1535
|
+
*/
|
|
1536
|
+
protected _deleteMany<T extends PgTable>(table: T, where: Record<string, any> | SQL | undefined): Promise<T['$inferSelect'][]>;
|
|
1537
|
+
/**
|
|
1538
|
+
* Count records
|
|
1539
|
+
*
|
|
1540
|
+
* @param table - Drizzle table schema
|
|
1541
|
+
* @param where - Optional object or SQL condition
|
|
1542
|
+
* @returns Number of records
|
|
1543
|
+
*
|
|
1544
|
+
* @example
|
|
1545
|
+
* ```typescript
|
|
1546
|
+
* const total = await this._count(users);
|
|
1547
|
+
* const activeUsers = await this._count(users, { active: true });
|
|
1548
|
+
* ```
|
|
1549
|
+
*/
|
|
1550
|
+
protected _count<T extends PgTable>(table: T, where?: Record<string, any> | SQL | undefined): Promise<number>;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
export { BaseRepository, type DatabaseClients, type DrizzleConfigOptions, type PoolConfig, RepositoryError, type RetryConfig, type TransactionContext, type TransactionDB, Transactional, type TransactionalOptions, auditFields, checkConnection, closeDatabase, count, create, createDatabaseConnection, createDatabaseFromEnv, createMany, createSchema, deleteMany, deleteOne, detectDialect, enumText, findMany, findOne, foreignKey, fromPostgresError, generateDrizzleConfigFile, getDatabase, getDatabaseInfo, getDrizzleConfig, getSchemaInfo, getTransaction, id, initDatabase, optionalForeignKey, packageNameToSchema, publishingFields, runWithTransaction, setDatabase, softDelete, timestamps, typedJsonb, updateMany, updateOne, upsert, utcTimestamp, uuid, verificationTimestamp };
|