@veloxts/orm 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +114 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +156 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +117 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +138 -0
- package/dist/plugin.js.map +1 -0
- package/dist/types.d.ts +146 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -2
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database client wrapper for Prisma
|
|
3
|
+
*
|
|
4
|
+
* Provides lifecycle management and connection state tracking
|
|
5
|
+
* for Prisma clients in a type-safe manner.
|
|
6
|
+
*
|
|
7
|
+
* @module client
|
|
8
|
+
*/
|
|
9
|
+
import type { ConnectionStatus, DatabaseClient, DatabaseWrapperConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Wrapped database client with connection lifecycle management
|
|
12
|
+
*
|
|
13
|
+
* @template TClient - Type of the underlying Prisma client
|
|
14
|
+
*/
|
|
15
|
+
export interface Database<TClient extends DatabaseClient> {
|
|
16
|
+
/**
|
|
17
|
+
* The underlying Prisma client instance
|
|
18
|
+
*
|
|
19
|
+
* Use this for all database queries. The client is always available,
|
|
20
|
+
* but queries will fail if not connected.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const db = createDatabase({ client: prisma });
|
|
25
|
+
* await db.connect();
|
|
26
|
+
*
|
|
27
|
+
* const users = await db.client.user.findMany();
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
readonly client: TClient;
|
|
31
|
+
/**
|
|
32
|
+
* Current connection status
|
|
33
|
+
*/
|
|
34
|
+
readonly status: ConnectionStatus;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the database is connected
|
|
37
|
+
*
|
|
38
|
+
* Convenience getter equivalent to `status.isConnected`
|
|
39
|
+
*/
|
|
40
|
+
readonly isConnected: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Establishes connection to the database
|
|
43
|
+
*
|
|
44
|
+
* @throws {VeloxError} If already connected or connection fails
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const db = createDatabase({ client: prisma });
|
|
49
|
+
* await db.connect();
|
|
50
|
+
* console.log(db.isConnected); // true
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
connect(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Disconnects from the database
|
|
56
|
+
*
|
|
57
|
+
* @throws {VeloxError} If not connected or disconnection fails
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* await db.disconnect();
|
|
62
|
+
* console.log(db.isConnected); // false
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
disconnect(): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a database wrapper with connection lifecycle management
|
|
69
|
+
*
|
|
70
|
+
* This wrapper provides:
|
|
71
|
+
* - Connection state tracking
|
|
72
|
+
* - Controlled connect/disconnect methods
|
|
73
|
+
* - Type-safe access to the underlying client
|
|
74
|
+
*
|
|
75
|
+
* The client is NOT automatically connected - call `connect()` explicitly
|
|
76
|
+
* or use `createDatabasePlugin` for automatic lifecycle management.
|
|
77
|
+
*
|
|
78
|
+
* @template TClient - Type of the Prisma client
|
|
79
|
+
* @param config - Database configuration with client instance
|
|
80
|
+
* @returns Database wrapper with lifecycle management
|
|
81
|
+
*
|
|
82
|
+
* @throws {VeloxError} If config is invalid or client doesn't implement DatabaseClient
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { PrismaClient } from '@prisma/client';
|
|
87
|
+
* import { createDatabase } from '@veloxts/orm';
|
|
88
|
+
*
|
|
89
|
+
* const prisma = new PrismaClient();
|
|
90
|
+
* const db = createDatabase({ client: prisma });
|
|
91
|
+
*
|
|
92
|
+
* // Manual connection management
|
|
93
|
+
* await db.connect();
|
|
94
|
+
* const users = await db.client.user.findMany();
|
|
95
|
+
* await db.disconnect();
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* // Check connection status
|
|
101
|
+
* const db = createDatabase({ client: prisma });
|
|
102
|
+
*
|
|
103
|
+
* console.log(db.isConnected); // false
|
|
104
|
+
* console.log(db.status.state); // 'disconnected'
|
|
105
|
+
*
|
|
106
|
+
* await db.connect();
|
|
107
|
+
*
|
|
108
|
+
* console.log(db.isConnected); // true
|
|
109
|
+
* console.log(db.status.state); // 'connected'
|
|
110
|
+
* console.log(db.status.connectedAt); // Date
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export declare function createDatabase<TClient extends DatabaseClient>(config: DatabaseWrapperConfig<TClient>): Database<TClient>;
|
|
114
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAOpB;;;;GAIG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,SAAS,cAAc;IACtD;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAElC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B;;;;;;;;;;;OAWG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,cAAc,EAC3D,MAAM,EAAE,qBAAqB,CAAC,OAAO,CAAC,GACrC,QAAQ,CAAC,OAAO,CAAC,CAgInB"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database client wrapper for Prisma
|
|
3
|
+
*
|
|
4
|
+
* Provides lifecycle management and connection state tracking
|
|
5
|
+
* for Prisma clients in a type-safe manner.
|
|
6
|
+
*
|
|
7
|
+
* @module client
|
|
8
|
+
*/
|
|
9
|
+
import { ConfigurationError, VeloxError } from '@veloxts/core';
|
|
10
|
+
import { isDatabaseClient } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Creates a database wrapper with connection lifecycle management
|
|
13
|
+
*
|
|
14
|
+
* This wrapper provides:
|
|
15
|
+
* - Connection state tracking
|
|
16
|
+
* - Controlled connect/disconnect methods
|
|
17
|
+
* - Type-safe access to the underlying client
|
|
18
|
+
*
|
|
19
|
+
* The client is NOT automatically connected - call `connect()` explicitly
|
|
20
|
+
* or use `createDatabasePlugin` for automatic lifecycle management.
|
|
21
|
+
*
|
|
22
|
+
* @template TClient - Type of the Prisma client
|
|
23
|
+
* @param config - Database configuration with client instance
|
|
24
|
+
* @returns Database wrapper with lifecycle management
|
|
25
|
+
*
|
|
26
|
+
* @throws {VeloxError} If config is invalid or client doesn't implement DatabaseClient
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { PrismaClient } from '@prisma/client';
|
|
31
|
+
* import { createDatabase } from '@veloxts/orm';
|
|
32
|
+
*
|
|
33
|
+
* const prisma = new PrismaClient();
|
|
34
|
+
* const db = createDatabase({ client: prisma });
|
|
35
|
+
*
|
|
36
|
+
* // Manual connection management
|
|
37
|
+
* await db.connect();
|
|
38
|
+
* const users = await db.client.user.findMany();
|
|
39
|
+
* await db.disconnect();
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // Check connection status
|
|
45
|
+
* const db = createDatabase({ client: prisma });
|
|
46
|
+
*
|
|
47
|
+
* console.log(db.isConnected); // false
|
|
48
|
+
* console.log(db.status.state); // 'disconnected'
|
|
49
|
+
*
|
|
50
|
+
* await db.connect();
|
|
51
|
+
*
|
|
52
|
+
* console.log(db.isConnected); // true
|
|
53
|
+
* console.log(db.status.state); // 'connected'
|
|
54
|
+
* console.log(db.status.connectedAt); // Date
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function createDatabase(config) {
|
|
58
|
+
// Validate configuration
|
|
59
|
+
if (!config || typeof config !== 'object') {
|
|
60
|
+
throw new ConfigurationError('Database configuration is required');
|
|
61
|
+
}
|
|
62
|
+
if (!config.client) {
|
|
63
|
+
throw new ConfigurationError('Database client is required in configuration');
|
|
64
|
+
}
|
|
65
|
+
// Validate that the client implements DatabaseClient interface
|
|
66
|
+
if (!isDatabaseClient(config.client)) {
|
|
67
|
+
throw new ConfigurationError('Database client must implement $connect and $disconnect methods');
|
|
68
|
+
}
|
|
69
|
+
// Internal state
|
|
70
|
+
const state = {
|
|
71
|
+
connectionState: 'disconnected',
|
|
72
|
+
connectedAt: undefined,
|
|
73
|
+
};
|
|
74
|
+
// PERFORMANCE: Cached status object to avoid creating new objects on each access
|
|
75
|
+
// Updated only when connection state changes
|
|
76
|
+
let cachedStatus = buildStatusObject();
|
|
77
|
+
/**
|
|
78
|
+
* Builds a new status object from current state
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
function buildStatusObject() {
|
|
82
|
+
return {
|
|
83
|
+
state: state.connectionState,
|
|
84
|
+
isConnected: state.connectionState === 'connected',
|
|
85
|
+
connectedAt: state.connectedAt,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Updates the cached status object when state changes
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
function updateCachedStatus() {
|
|
93
|
+
cachedStatus = buildStatusObject();
|
|
94
|
+
}
|
|
95
|
+
// Connection method
|
|
96
|
+
async function connect() {
|
|
97
|
+
if (state.connectionState === 'connected') {
|
|
98
|
+
throw new VeloxError('Database is already connected', 500, 'DATABASE_ALREADY_CONNECTED');
|
|
99
|
+
}
|
|
100
|
+
if (state.connectionState === 'connecting') {
|
|
101
|
+
throw new VeloxError('Database connection is already in progress', 500, 'DATABASE_CONNECTION_IN_PROGRESS');
|
|
102
|
+
}
|
|
103
|
+
state.connectionState = 'connecting';
|
|
104
|
+
updateCachedStatus();
|
|
105
|
+
try {
|
|
106
|
+
await config.client.$connect();
|
|
107
|
+
state.connectionState = 'connected';
|
|
108
|
+
state.connectedAt = new Date();
|
|
109
|
+
updateCachedStatus();
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
state.connectionState = 'disconnected';
|
|
113
|
+
updateCachedStatus();
|
|
114
|
+
throw new VeloxError(`Failed to connect to database: ${error instanceof Error ? error.message : String(error)}`, 500, 'DATABASE_CONNECTION_ERROR');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Disconnection method
|
|
118
|
+
async function disconnect() {
|
|
119
|
+
if (state.connectionState === 'disconnected') {
|
|
120
|
+
throw new VeloxError('Database is not connected', 500, 'DATABASE_NOT_CONNECTED');
|
|
121
|
+
}
|
|
122
|
+
if (state.connectionState === 'disconnecting') {
|
|
123
|
+
throw new VeloxError('Database disconnection is already in progress', 500, 'DATABASE_DISCONNECTION_IN_PROGRESS');
|
|
124
|
+
}
|
|
125
|
+
state.connectionState = 'disconnecting';
|
|
126
|
+
updateCachedStatus();
|
|
127
|
+
try {
|
|
128
|
+
await config.client.$disconnect();
|
|
129
|
+
state.connectionState = 'disconnected';
|
|
130
|
+
state.connectedAt = undefined;
|
|
131
|
+
updateCachedStatus();
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
// Even if disconnect fails, mark as disconnected
|
|
135
|
+
state.connectionState = 'disconnected';
|
|
136
|
+
state.connectedAt = undefined;
|
|
137
|
+
updateCachedStatus();
|
|
138
|
+
throw new VeloxError(`Failed to disconnect from database: ${error instanceof Error ? error.message : String(error)}`, 500, 'DATABASE_DISCONNECTION_ERROR');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Return the database wrapper object with proper getters for reactive properties
|
|
142
|
+
// PERFORMANCE: status getter returns cached object instead of creating new one
|
|
143
|
+
const database = {
|
|
144
|
+
client: config.client,
|
|
145
|
+
connect,
|
|
146
|
+
disconnect,
|
|
147
|
+
get status() {
|
|
148
|
+
return cachedStatus;
|
|
149
|
+
},
|
|
150
|
+
get isConnected() {
|
|
151
|
+
return state.connectionState === 'connected';
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
return database;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @veloxts/orm - Laravel-inspired Prisma wrapper for VeloxTS framework
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe database integration with:
|
|
5
|
+
* - Context-based database access (`ctx.db.user.findUnique(...)`)
|
|
6
|
+
* - VeloxApp plugin integration with automatic lifecycle management
|
|
7
|
+
* - Connection state tracking and error handling
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Setup
|
|
12
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
13
|
+
* import { PrismaClient } from '@prisma/client';
|
|
14
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
15
|
+
*
|
|
16
|
+
* const prisma = new PrismaClient();
|
|
17
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
18
|
+
*
|
|
19
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
20
|
+
* await app.start();
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Using ctx.db in procedure handlers
|
|
26
|
+
* getUser: procedure()
|
|
27
|
+
* .input(z.object({ id: z.string().uuid() }))
|
|
28
|
+
* .query(async ({ input, ctx }) => {
|
|
29
|
+
* return ctx.db.user.findUnique({ where: { id: input.id } });
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @module @veloxts/orm
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Package version
|
|
37
|
+
*/
|
|
38
|
+
export declare const ORM_VERSION: "0.1.0";
|
|
39
|
+
export type {
|
|
40
|
+
/**
|
|
41
|
+
* Connection state enum values
|
|
42
|
+
*/
|
|
43
|
+
ConnectionState,
|
|
44
|
+
/**
|
|
45
|
+
* Connection status information
|
|
46
|
+
*/
|
|
47
|
+
ConnectionStatus,
|
|
48
|
+
/**
|
|
49
|
+
* Base interface for Prisma clients
|
|
50
|
+
*/
|
|
51
|
+
DatabaseClient,
|
|
52
|
+
/**
|
|
53
|
+
* Configuration for database wrapper
|
|
54
|
+
*/
|
|
55
|
+
DatabaseWrapperConfig,
|
|
56
|
+
/**
|
|
57
|
+
* Infer client type from config
|
|
58
|
+
*/
|
|
59
|
+
InferClientType,
|
|
60
|
+
/**
|
|
61
|
+
* Infer database client type
|
|
62
|
+
*/
|
|
63
|
+
InferDatabaseClient,
|
|
64
|
+
/**
|
|
65
|
+
* Plugin configuration options
|
|
66
|
+
*/
|
|
67
|
+
OrmPluginConfig, } from './types.js';
|
|
68
|
+
export { isDatabaseClient } from './types.js';
|
|
69
|
+
export type {
|
|
70
|
+
/**
|
|
71
|
+
* Database wrapper interface with lifecycle management
|
|
72
|
+
*/
|
|
73
|
+
Database, } from './client.js';
|
|
74
|
+
export {
|
|
75
|
+
/**
|
|
76
|
+
* Create a database wrapper with connection lifecycle management
|
|
77
|
+
*
|
|
78
|
+
* Use this for manual connection management. For automatic lifecycle
|
|
79
|
+
* management with VeloxApp, use `createDatabasePlugin` instead.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const db = createDatabase({ client: new PrismaClient() });
|
|
84
|
+
* await db.connect();
|
|
85
|
+
*
|
|
86
|
+
* const users = await db.client.user.findMany();
|
|
87
|
+
*
|
|
88
|
+
* await db.disconnect();
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
createDatabase, } from './client.js';
|
|
92
|
+
export {
|
|
93
|
+
/**
|
|
94
|
+
* Create a database plugin for VeloxApp integration
|
|
95
|
+
*
|
|
96
|
+
* This is the recommended way to integrate Prisma with VeloxTS.
|
|
97
|
+
* The plugin automatically:
|
|
98
|
+
* - Connects to the database when the app starts
|
|
99
|
+
* - Disconnects during graceful shutdown
|
|
100
|
+
* - Adds `ctx.db` to procedure handlers
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
105
|
+
* import { PrismaClient } from '@prisma/client';
|
|
106
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
107
|
+
*
|
|
108
|
+
* const prisma = new PrismaClient();
|
|
109
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
110
|
+
*
|
|
111
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
112
|
+
* await app.start();
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
createDatabasePlugin, } from './plugin.js';
|
|
116
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH;;GAEG;AACH,eAAO,MAAM,WAAW,EAAG,OAAgB,CAAC;AAM5C,YAAY;AACV;;GAEG;AACH,eAAe;AACf;;GAEG;AACH,gBAAgB;AAChB;;GAEG;AACH,cAAc;AACd;;GAEG;AACH,qBAAqB;AACrB;;GAEG;AACH,eAAe;AACf;;GAEG;AACH,mBAAmB;AACnB;;GAEG;AACH,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAM9C,YAAY;AACV;;GAEG;AACH,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,OAAO;AACL;;;;;;;;;;;;;;;GAeG;AACH,cAAc,GACf,MAAM,aAAa,CAAC;AAMrB,OAAO;AACL;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @veloxts/orm - Laravel-inspired Prisma wrapper for VeloxTS framework
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe database integration with:
|
|
5
|
+
* - Context-based database access (`ctx.db.user.findUnique(...)`)
|
|
6
|
+
* - VeloxApp plugin integration with automatic lifecycle management
|
|
7
|
+
* - Connection state tracking and error handling
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Setup
|
|
12
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
13
|
+
* import { PrismaClient } from '@prisma/client';
|
|
14
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
15
|
+
*
|
|
16
|
+
* const prisma = new PrismaClient();
|
|
17
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
18
|
+
*
|
|
19
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
20
|
+
* await app.start();
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Using ctx.db in procedure handlers
|
|
26
|
+
* getUser: procedure()
|
|
27
|
+
* .input(z.object({ id: z.string().uuid() }))
|
|
28
|
+
* .query(async ({ input, ctx }) => {
|
|
29
|
+
* return ctx.db.user.findUnique({ where: { id: input.id } });
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @module @veloxts/orm
|
|
34
|
+
*/
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Version
|
|
37
|
+
// ============================================================================
|
|
38
|
+
/**
|
|
39
|
+
* Package version
|
|
40
|
+
*/
|
|
41
|
+
export const ORM_VERSION = '0.1.0';
|
|
42
|
+
export { isDatabaseClient } from './types.js';
|
|
43
|
+
export {
|
|
44
|
+
/**
|
|
45
|
+
* Create a database wrapper with connection lifecycle management
|
|
46
|
+
*
|
|
47
|
+
* Use this for manual connection management. For automatic lifecycle
|
|
48
|
+
* management with VeloxApp, use `createDatabasePlugin` instead.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const db = createDatabase({ client: new PrismaClient() });
|
|
53
|
+
* await db.connect();
|
|
54
|
+
*
|
|
55
|
+
* const users = await db.client.user.findMany();
|
|
56
|
+
*
|
|
57
|
+
* await db.disconnect();
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
createDatabase, } from './client.js';
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// Plugin
|
|
63
|
+
// ============================================================================
|
|
64
|
+
export {
|
|
65
|
+
/**
|
|
66
|
+
* Create a database plugin for VeloxApp integration
|
|
67
|
+
*
|
|
68
|
+
* This is the recommended way to integrate Prisma with VeloxTS.
|
|
69
|
+
* The plugin automatically:
|
|
70
|
+
* - Connects to the database when the app starts
|
|
71
|
+
* - Disconnects during graceful shutdown
|
|
72
|
+
* - Adds `ctx.db` to procedure handlers
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
77
|
+
* import { PrismaClient } from '@prisma/client';
|
|
78
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
79
|
+
*
|
|
80
|
+
* const prisma = new PrismaClient();
|
|
81
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
82
|
+
*
|
|
83
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
84
|
+
* await app.start();
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
createDatabasePlugin, } from './plugin.js';
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAgB,CAAC;AAoC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAY9C,OAAO;AACL;;;;;;;;;;;;;;;GAeG;AACH,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,+EAA+E;AAC/E,SAAS;AACT,+EAA+E;AAE/E,OAAO;AACL;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,oBAAoB,GACrB,MAAM,aAAa,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VeloxApp plugin for database integration
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic database lifecycle management via the VeloxTS plugin system.
|
|
5
|
+
* Connects on app start, disconnects on app shutdown.
|
|
6
|
+
*
|
|
7
|
+
* @module plugin
|
|
8
|
+
*/
|
|
9
|
+
import type { DatabaseClient, OrmPluginConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Extend BaseContext to include the database client
|
|
12
|
+
*
|
|
13
|
+
* After registering the database plugin, `ctx.db` will be available
|
|
14
|
+
* in all procedure handlers with full type information.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* // In your app setup
|
|
19
|
+
* import { PrismaClient } from '@prisma/client';
|
|
20
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
21
|
+
*
|
|
22
|
+
* const prisma = new PrismaClient();
|
|
23
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
24
|
+
*
|
|
25
|
+
* // In your procedure handlers
|
|
26
|
+
* getUser: procedure()
|
|
27
|
+
* .input(z.object({ id: z.string() }))
|
|
28
|
+
* .query(async ({ input, ctx }) => {
|
|
29
|
+
* // ctx.db is typed as your PrismaClient
|
|
30
|
+
* return ctx.db.user.findUnique({ where: { id: input.id } });
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* To get full type inference for your specific Prisma schema,
|
|
35
|
+
* add this to your app's declaration file:
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // In your app's types.d.ts or similar
|
|
40
|
+
* import type { PrismaClient } from '@prisma/client';
|
|
41
|
+
*
|
|
42
|
+
* declare module '@veloxts/core' {
|
|
43
|
+
* interface BaseContext {
|
|
44
|
+
* db: PrismaClient;
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
declare module '@veloxts/core' {
|
|
50
|
+
interface BaseContext {
|
|
51
|
+
/**
|
|
52
|
+
* Database client for executing queries
|
|
53
|
+
*
|
|
54
|
+
* This property is added by the @veloxts/orm plugin.
|
|
55
|
+
* The actual type depends on your Prisma schema.
|
|
56
|
+
*/
|
|
57
|
+
db: DatabaseClient;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates a database plugin for VeloxApp integration
|
|
62
|
+
*
|
|
63
|
+
* This plugin:
|
|
64
|
+
* - Wraps your Prisma client with connection management
|
|
65
|
+
* - Automatically connects when the app starts
|
|
66
|
+
* - Automatically disconnects during graceful shutdown
|
|
67
|
+
* - Adds `db` to the request context for use in procedure handlers
|
|
68
|
+
*
|
|
69
|
+
* @template TClient - Type of the Prisma client
|
|
70
|
+
* @param config - Plugin configuration with Prisma client
|
|
71
|
+
* @returns A VeloxPlugin that can be registered with `app.use()`
|
|
72
|
+
*
|
|
73
|
+
* @throws {ConfigurationError} If config is invalid or client is missing
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
78
|
+
* import { PrismaClient } from '@prisma/client';
|
|
79
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
80
|
+
*
|
|
81
|
+
* const prisma = new PrismaClient();
|
|
82
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
83
|
+
*
|
|
84
|
+
* // Register the database plugin
|
|
85
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
86
|
+
*
|
|
87
|
+
* // Start the app (database connects automatically)
|
|
88
|
+
* await app.start();
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // Using ctx.db in procedures
|
|
94
|
+
* import { defineProcedures, procedure } from '@veloxts/router';
|
|
95
|
+
* import { z } from '@veloxts/validation';
|
|
96
|
+
*
|
|
97
|
+
* export const userProcedures = defineProcedures('users', {
|
|
98
|
+
* getUser: procedure()
|
|
99
|
+
* .input(z.object({ id: z.string().uuid() }))
|
|
100
|
+
* .query(async ({ input, ctx }) => {
|
|
101
|
+
* // ctx.db is your Prisma client
|
|
102
|
+
* const user = await ctx.db.user.findUnique({
|
|
103
|
+
* where: { id: input.id }
|
|
104
|
+
* });
|
|
105
|
+
* return user;
|
|
106
|
+
* }),
|
|
107
|
+
*
|
|
108
|
+
* createUser: procedure()
|
|
109
|
+
* .input(z.object({ name: z.string(), email: z.string().email() }))
|
|
110
|
+
* .mutation(async ({ input, ctx }) => {
|
|
111
|
+
* return ctx.db.user.create({ data: input });
|
|
112
|
+
* }),
|
|
113
|
+
* });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function createDatabasePlugin<TClient extends DatabaseClient>(config: OrmPluginConfig<TClient>): import("@veloxts/core").VeloxPlugin<import("fastify").FastifyPluginOptions>;
|
|
117
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,WAAW;QACnB;;;;;WAKG;QACH,EAAE,EAAE,cAAc,CAAC;KACpB;CACF;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,SAAS,cAAc,EACjE,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,+EA2EjC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VeloxApp plugin for database integration
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic database lifecycle management via the VeloxTS plugin system.
|
|
5
|
+
* Connects on app start, disconnects on app shutdown.
|
|
6
|
+
*
|
|
7
|
+
* @module plugin
|
|
8
|
+
*/
|
|
9
|
+
import { ConfigurationError, definePlugin } from '@veloxts/core';
|
|
10
|
+
import { createDatabase } from './client.js';
|
|
11
|
+
import { isDatabaseClient } from './types.js';
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Plugin Implementation
|
|
14
|
+
// ============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Version of the ORM plugin
|
|
17
|
+
*/
|
|
18
|
+
const ORM_PLUGIN_VERSION = '0.1.0';
|
|
19
|
+
/**
|
|
20
|
+
* Default plugin name
|
|
21
|
+
*/
|
|
22
|
+
const DEFAULT_PLUGIN_NAME = '@veloxts/orm';
|
|
23
|
+
/**
|
|
24
|
+
* Creates a database plugin for VeloxApp integration
|
|
25
|
+
*
|
|
26
|
+
* This plugin:
|
|
27
|
+
* - Wraps your Prisma client with connection management
|
|
28
|
+
* - Automatically connects when the app starts
|
|
29
|
+
* - Automatically disconnects during graceful shutdown
|
|
30
|
+
* - Adds `db` to the request context for use in procedure handlers
|
|
31
|
+
*
|
|
32
|
+
* @template TClient - Type of the Prisma client
|
|
33
|
+
* @param config - Plugin configuration with Prisma client
|
|
34
|
+
* @returns A VeloxPlugin that can be registered with `app.use()`
|
|
35
|
+
*
|
|
36
|
+
* @throws {ConfigurationError} If config is invalid or client is missing
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { createVeloxApp } from '@veloxts/core';
|
|
41
|
+
* import { PrismaClient } from '@prisma/client';
|
|
42
|
+
* import { createDatabasePlugin } from '@veloxts/orm';
|
|
43
|
+
*
|
|
44
|
+
* const prisma = new PrismaClient();
|
|
45
|
+
* const app = await createVeloxApp({ port: 3210 });
|
|
46
|
+
*
|
|
47
|
+
* // Register the database plugin
|
|
48
|
+
* await app.use(createDatabasePlugin({ client: prisma }));
|
|
49
|
+
*
|
|
50
|
+
* // Start the app (database connects automatically)
|
|
51
|
+
* await app.start();
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Using ctx.db in procedures
|
|
57
|
+
* import { defineProcedures, procedure } from '@veloxts/router';
|
|
58
|
+
* import { z } from '@veloxts/validation';
|
|
59
|
+
*
|
|
60
|
+
* export const userProcedures = defineProcedures('users', {
|
|
61
|
+
* getUser: procedure()
|
|
62
|
+
* .input(z.object({ id: z.string().uuid() }))
|
|
63
|
+
* .query(async ({ input, ctx }) => {
|
|
64
|
+
* // ctx.db is your Prisma client
|
|
65
|
+
* const user = await ctx.db.user.findUnique({
|
|
66
|
+
* where: { id: input.id }
|
|
67
|
+
* });
|
|
68
|
+
* return user;
|
|
69
|
+
* }),
|
|
70
|
+
*
|
|
71
|
+
* createUser: procedure()
|
|
72
|
+
* .input(z.object({ name: z.string(), email: z.string().email() }))
|
|
73
|
+
* .mutation(async ({ input, ctx }) => {
|
|
74
|
+
* return ctx.db.user.create({ data: input });
|
|
75
|
+
* }),
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function createDatabasePlugin(config) {
|
|
80
|
+
// Validate configuration at plugin creation time
|
|
81
|
+
if (!config || typeof config !== 'object') {
|
|
82
|
+
throw new ConfigurationError('Database plugin configuration is required');
|
|
83
|
+
}
|
|
84
|
+
if (!config.client) {
|
|
85
|
+
throw new ConfigurationError('Database client is required. Provide a Prisma client instance in config.client');
|
|
86
|
+
}
|
|
87
|
+
if (!isDatabaseClient(config.client)) {
|
|
88
|
+
throw new ConfigurationError('Database client must implement $connect and $disconnect methods. ' +
|
|
89
|
+
'Ensure you are passing a valid Prisma client instance.');
|
|
90
|
+
}
|
|
91
|
+
const pluginName = config.name ?? DEFAULT_PLUGIN_NAME;
|
|
92
|
+
// Plugin state - holds the database wrapper
|
|
93
|
+
const state = {
|
|
94
|
+
database: null,
|
|
95
|
+
};
|
|
96
|
+
return definePlugin({
|
|
97
|
+
name: pluginName,
|
|
98
|
+
version: ORM_PLUGIN_VERSION,
|
|
99
|
+
async register(server) {
|
|
100
|
+
// Create the database wrapper
|
|
101
|
+
state.database = createDatabase({ client: config.client });
|
|
102
|
+
// Connect to the database
|
|
103
|
+
await state.database.connect();
|
|
104
|
+
// Add database client to request context via onRequest hook
|
|
105
|
+
server.addHook('onRequest', async (request) => {
|
|
106
|
+
// The context should be created by @veloxts/core's onRequest hook
|
|
107
|
+
// which runs before this hook (due to plugin registration order)
|
|
108
|
+
if (request.context) {
|
|
109
|
+
// Extend the context with the database client using Object.defineProperty
|
|
110
|
+
// for proper property definition without type assertion side effects
|
|
111
|
+
Object.defineProperty(request.context, 'db', {
|
|
112
|
+
value: config.client,
|
|
113
|
+
writable: false,
|
|
114
|
+
enumerable: true,
|
|
115
|
+
configurable: true, // Allow redefinition for testing
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// Register shutdown hook using Fastify's onClose hook
|
|
120
|
+
// This ensures the database disconnects during graceful shutdown
|
|
121
|
+
server.addHook('onClose', async () => {
|
|
122
|
+
if (state.database?.isConnected) {
|
|
123
|
+
try {
|
|
124
|
+
await state.database.disconnect();
|
|
125
|
+
server.log.info('Database disconnected successfully during shutdown');
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
// Log error but don't rethrow - allow graceful shutdown to continue
|
|
129
|
+
server.log.error({ err: error instanceof Error ? error : new Error(String(error)) }, 'Failed to disconnect database during shutdown');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
// Log successful registration
|
|
134
|
+
server.log.info(`Database plugin "${pluginName}" registered successfully`);
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for @veloxts/orm
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe abstractions for Prisma client integration
|
|
5
|
+
* without requiring direct Prisma dependency.
|
|
6
|
+
*
|
|
7
|
+
* @module types
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Extend the VeloxErrorCodeRegistry to include ORM-specific error codes
|
|
11
|
+
*
|
|
12
|
+
* This enables type-safe error handling for database-related errors
|
|
13
|
+
*/
|
|
14
|
+
declare module '@veloxts/core' {
|
|
15
|
+
interface VeloxErrorCodeRegistry {
|
|
16
|
+
orm: 'DATABASE_CONNECTION_ERROR' | 'DATABASE_DISCONNECTION_ERROR' | 'DATABASE_NOT_CONNECTED' | 'DATABASE_ALREADY_CONNECTED' | 'DATABASE_CONNECTION_IN_PROGRESS' | 'DATABASE_DISCONNECTION_IN_PROGRESS';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Minimal interface that any Prisma client must satisfy
|
|
21
|
+
*
|
|
22
|
+
* This interface allows the ORM package to work with any Prisma client
|
|
23
|
+
* without requiring @prisma/client as a direct dependency.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { PrismaClient } from '@prisma/client';
|
|
28
|
+
*
|
|
29
|
+
* // PrismaClient satisfies DatabaseClient
|
|
30
|
+
* const prisma: DatabaseClient = new PrismaClient();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export interface DatabaseClient {
|
|
34
|
+
/**
|
|
35
|
+
* Establishes connection to the database
|
|
36
|
+
*
|
|
37
|
+
* Called automatically when using createDatabasePlugin,
|
|
38
|
+
* or can be called manually with createDatabase.
|
|
39
|
+
*/
|
|
40
|
+
$connect: () => Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Disconnects from the database
|
|
43
|
+
*
|
|
44
|
+
* Called automatically during app shutdown when using createDatabasePlugin,
|
|
45
|
+
* or can be called manually with createDatabase.
|
|
46
|
+
*/
|
|
47
|
+
$disconnect: () => Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Type guard to check if an object is a valid DatabaseClient
|
|
51
|
+
*
|
|
52
|
+
* Uses property checks to ensure the object has the required methods
|
|
53
|
+
* without using type assertions.
|
|
54
|
+
*
|
|
55
|
+
* @param value - Value to check
|
|
56
|
+
* @returns true if value satisfies DatabaseClient interface
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* if (isDatabaseClient(unknownValue)) {
|
|
61
|
+
* await unknownValue.$connect();
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function isDatabaseClient(value: unknown): value is DatabaseClient;
|
|
66
|
+
/**
|
|
67
|
+
* Configuration options for the database plugin
|
|
68
|
+
*
|
|
69
|
+
* @template TClient - Type of the Prisma client
|
|
70
|
+
*/
|
|
71
|
+
export interface OrmPluginConfig<TClient extends DatabaseClient> {
|
|
72
|
+
/**
|
|
73
|
+
* The Prisma client instance to use
|
|
74
|
+
*
|
|
75
|
+
* Must be an already-instantiated PrismaClient. Connection will be
|
|
76
|
+
* managed by the plugin (connect on start, disconnect on shutdown).
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const prisma = new PrismaClient();
|
|
81
|
+
* const plugin = createDatabasePlugin({ client: prisma });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
client: TClient;
|
|
85
|
+
/**
|
|
86
|
+
* Custom name for the plugin registration
|
|
87
|
+
*
|
|
88
|
+
* Defaults to '@veloxts/orm'. Useful when registering multiple database
|
|
89
|
+
* connections with different names.
|
|
90
|
+
*
|
|
91
|
+
* @default '@veloxts/orm'
|
|
92
|
+
*/
|
|
93
|
+
name?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Configuration options for the database wrapper
|
|
97
|
+
*/
|
|
98
|
+
export interface DatabaseWrapperConfig<TClient extends DatabaseClient> {
|
|
99
|
+
/**
|
|
100
|
+
* The Prisma client instance to wrap
|
|
101
|
+
*/
|
|
102
|
+
client: TClient;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Possible states of a database connection
|
|
106
|
+
*/
|
|
107
|
+
export type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'disconnecting';
|
|
108
|
+
/**
|
|
109
|
+
* Database connection status information
|
|
110
|
+
*/
|
|
111
|
+
export interface ConnectionStatus {
|
|
112
|
+
/**
|
|
113
|
+
* Current connection state
|
|
114
|
+
*/
|
|
115
|
+
state: ConnectionState;
|
|
116
|
+
/**
|
|
117
|
+
* Whether the database is currently connected and ready for queries
|
|
118
|
+
*/
|
|
119
|
+
isConnected: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Timestamp of last successful connection, if any
|
|
122
|
+
*/
|
|
123
|
+
connectedAt?: Date;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Infer the client type from an OrmPluginConfig
|
|
127
|
+
*
|
|
128
|
+
* @template T - OrmPluginConfig type
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const config = { client: new PrismaClient() };
|
|
133
|
+
* type Client = InferClientType<typeof config>;
|
|
134
|
+
* // Client = PrismaClient
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export type InferClientType<T> = T extends OrmPluginConfig<infer C> ? C : never;
|
|
138
|
+
/**
|
|
139
|
+
* Infer the client type from a Database wrapper
|
|
140
|
+
*
|
|
141
|
+
* @template T - Database wrapper type
|
|
142
|
+
*/
|
|
143
|
+
export type InferDatabaseClient<T> = T extends {
|
|
144
|
+
client: infer C;
|
|
145
|
+
} ? C : never;
|
|
146
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;GAIG;AACH,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,sBAAsB;QAC9B,GAAG,EACC,2BAA2B,GAC3B,8BAA8B,GAC9B,wBAAwB,GACxB,4BAA4B,GAC5B,iCAAiC,GACjC,oCAAoC,CAAC;KAC1C;CACF;AAMD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9B;;;;;OAKG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAYxE;AAMD;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,cAAc;IAC7D;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,OAAO,SAAS,cAAc;IACnE;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,eAAe,CAAC;AAE5F;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC;IAEvB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEhF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS;IAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for @veloxts/orm
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe abstractions for Prisma client integration
|
|
5
|
+
* without requiring direct Prisma dependency.
|
|
6
|
+
*
|
|
7
|
+
* @module types
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Type guard to check if an object is a valid DatabaseClient
|
|
11
|
+
*
|
|
12
|
+
* Uses property checks to ensure the object has the required methods
|
|
13
|
+
* without using type assertions.
|
|
14
|
+
*
|
|
15
|
+
* @param value - Value to check
|
|
16
|
+
* @returns true if value satisfies DatabaseClient interface
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* if (isDatabaseClient(unknownValue)) {
|
|
21
|
+
* await unknownValue.$connect();
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function isDatabaseClient(value) {
|
|
26
|
+
if (typeof value !== 'object' || value === null) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
// Check for required methods
|
|
30
|
+
return ('$connect' in value &&
|
|
31
|
+
typeof value.$connect === 'function' &&
|
|
32
|
+
'$disconnect' in value &&
|
|
33
|
+
typeof value.$disconnect === 'function');
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2DH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6BAA6B;IAC7B,OAAO,CACL,UAAU,IAAI,KAAK;QACnB,OAAO,KAAK,CAAC,QAAQ,KAAK,UAAU;QACpC,aAAa,IAAI,KAAK;QACtB,OAAO,KAAK,CAAC,WAAW,KAAK,UAAU,CACxC,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/orm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Prisma wrapper with enhanced DX for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"fastify": "5.6.2",
|
|
16
|
-
"@veloxts/core": "0.
|
|
16
|
+
"@veloxts/core": "0.3.0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"typescript": "5.9.3",
|