@veloxts/orm 0.7.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @veloxts/orm
2
2
 
3
+ ## 0.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - chore(auth,core,create,cli,client,orm,mcp,router,validation,web): simplify code for clarity and maintainability
8
+ - Updated dependencies
9
+ - @veloxts/core@0.7.2
10
+
11
+ ## 0.7.1
12
+
13
+ ### Patch Changes
14
+
15
+ - security audit, bumps dependency packages
16
+ - Updated dependencies
17
+ - @veloxts/core@0.7.1
18
+
3
19
  ## 0.7.0
4
20
 
5
21
  ### Minor Changes
package/dist/client.js CHANGED
@@ -126,16 +126,15 @@ export function createDatabase(config) {
126
126
  updateCachedStatus();
127
127
  try {
128
128
  await config.client.$disconnect();
129
- state.connectionState = 'disconnected';
130
- state.connectedAt = undefined;
131
- updateCachedStatus();
132
129
  }
133
130
  catch (error) {
131
+ throw new VeloxError(`Failed to disconnect from database: ${error instanceof Error ? error.message : String(error)}`, 500, 'DATABASE_DISCONNECTION_ERROR');
132
+ }
133
+ finally {
134
134
  // Even if disconnect fails, mark as disconnected
135
135
  state.connectionState = 'disconnected';
136
136
  state.connectedAt = undefined;
137
137
  updateCachedStatus();
138
- throw new VeloxError(`Failed to disconnect from database: ${error instanceof Error ? error.message : String(error)}`, 500, 'DATABASE_DISCONNECTION_ERROR');
139
138
  }
140
139
  }
141
140
  // Return the database wrapper object with proper getters for reactive properties
package/dist/index.d.ts CHANGED
@@ -34,80 +34,8 @@
34
34
  */
35
35
  /** ORM package version */
36
36
  export declare const ORM_VERSION: string;
37
- export type {
38
- /**
39
- * Connection state enum values
40
- */
41
- ConnectionState,
42
- /**
43
- * Connection status information
44
- */
45
- ConnectionStatus,
46
- /**
47
- * Base interface for Prisma clients
48
- */
49
- DatabaseClient,
50
- /**
51
- * Configuration for database wrapper
52
- */
53
- DatabaseWrapperConfig,
54
- /**
55
- * Infer client type from config
56
- */
57
- InferClientType,
58
- /**
59
- * Infer database client type
60
- */
61
- InferDatabaseClient,
62
- /**
63
- * Plugin configuration options
64
- */
65
- OrmPluginConfig, } from './types.js';
37
+ export type { ConnectionState, ConnectionStatus, DatabaseClient, DatabaseWrapperConfig, InferClientType, InferDatabaseClient, OrmPluginConfig, } from './types.js';
66
38
  export { isDatabaseClient } from './types.js';
67
- export type {
68
- /**
69
- * Database wrapper interface with lifecycle management
70
- */
71
- Database, } from './client.js';
72
- export {
73
- /**
74
- * Create a database wrapper with connection lifecycle management
75
- *
76
- * Use this for manual connection management. For automatic lifecycle
77
- * management with VeloxApp, use `databasePlugin` instead.
78
- *
79
- * @example
80
- * ```typescript
81
- * const db = createDatabase({ client: new PrismaClient() });
82
- * await db.connect();
83
- *
84
- * const users = await db.client.user.findMany();
85
- *
86
- * await db.disconnect();
87
- * ```
88
- */
89
- createDatabase, } from './client.js';
90
- export {
91
- /**
92
- * Create a database plugin for VeloxApp integration
93
- *
94
- * This is the recommended way to integrate Prisma with VeloxTS.
95
- * The plugin automatically:
96
- * - Connects to the database when the app starts
97
- * - Disconnects during graceful shutdown
98
- * - Adds `ctx.db` to procedure handlers
99
- *
100
- * @example
101
- * ```typescript
102
- * import { veloxApp } from '@veloxts/core';
103
- * import { PrismaClient } from '@prisma/client';
104
- * import { databasePlugin } from '@veloxts/orm';
105
- *
106
- * const prisma = new PrismaClient();
107
- * const app = await veloxApp({ port: 3030 });
108
- *
109
- * await app.register(databasePlugin({ client: prisma }));
110
- * await app.start();
111
- * ```
112
- */
113
- databasePlugin, } from './plugin.js';
39
+ export type { Database } from './client.js';
40
+ export { createDatabase } from './client.js';
41
+ export { databasePlugin } from './plugin.js';
package/dist/index.js CHANGED
@@ -42,48 +42,8 @@ const packageJson = require('../package.json');
42
42
  /** ORM package version */
43
43
  export const ORM_VERSION = packageJson.version ?? '0.0.0-unknown';
44
44
  export { isDatabaseClient } from './types.js';
45
- export {
46
- /**
47
- * Create a database wrapper with connection lifecycle management
48
- *
49
- * Use this for manual connection management. For automatic lifecycle
50
- * management with VeloxApp, use `databasePlugin` instead.
51
- *
52
- * @example
53
- * ```typescript
54
- * const db = createDatabase({ client: new PrismaClient() });
55
- * await db.connect();
56
- *
57
- * const users = await db.client.user.findMany();
58
- *
59
- * await db.disconnect();
60
- * ```
61
- */
62
- createDatabase, } from './client.js';
45
+ export { createDatabase } from './client.js';
63
46
  // ============================================================================
64
47
  // Plugin
65
48
  // ============================================================================
66
- export {
67
- /**
68
- * Create a database plugin for VeloxApp integration
69
- *
70
- * This is the recommended way to integrate Prisma with VeloxTS.
71
- * The plugin automatically:
72
- * - Connects to the database when the app starts
73
- * - Disconnects during graceful shutdown
74
- * - Adds `ctx.db` to procedure handlers
75
- *
76
- * @example
77
- * ```typescript
78
- * import { veloxApp } from '@veloxts/core';
79
- * import { PrismaClient } from '@prisma/client';
80
- * import { databasePlugin } from '@veloxts/orm';
81
- *
82
- * const prisma = new PrismaClient();
83
- * const app = await veloxApp({ port: 3030 });
84
- *
85
- * await app.register(databasePlugin({ client: prisma }));
86
- * await app.start();
87
- * ```
88
- */
89
- databasePlugin, } from './plugin.js';
49
+ export { databasePlugin } from './plugin.js';
package/dist/plugin.js CHANGED
@@ -131,18 +131,13 @@ export function databasePlugin(config) {
131
131
  'Ensure you are passing a valid Prisma client instance.');
132
132
  }
133
133
  const pluginName = config.name ?? DEFAULT_PLUGIN_NAME;
134
- // Plugin state - holds the database wrapper
135
- const state = {
136
- database: null,
137
- };
134
+ let database = null;
138
135
  return definePlugin({
139
136
  name: pluginName,
140
137
  version: ORM_PLUGIN_VERSION,
141
138
  async register(server) {
142
- // Create database wrapper
143
- state.database = createDatabase({ client: config.client });
144
- // Connect to the database
145
- await state.database.connect();
139
+ database = createDatabase({ client: config.client });
140
+ await database.connect();
146
141
  // Add database client to request context via onRequest hook
147
142
  server.addHook('onRequest', async (request) => {
148
143
  // The context should be created by @veloxts/core's onRequest hook
@@ -158,12 +153,10 @@ export function databasePlugin(config) {
158
153
  });
159
154
  }
160
155
  });
161
- // Register shutdown hook using Fastify's onClose hook
162
- // This ensures the database disconnects during graceful shutdown
163
156
  server.addHook('onClose', async () => {
164
- if (state.database?.isConnected) {
157
+ if (database?.isConnected) {
165
158
  try {
166
- await state.database.disconnect();
159
+ await database.disconnect();
167
160
  server.log.info('Database disconnected successfully during shutdown');
168
161
  }
169
162
  catch (error) {
@@ -32,7 +32,3 @@ import type { TenantClientPool as ITenantClientPool, TenantClientPoolConfig } fr
32
32
  * ```
33
33
  */
34
34
  export declare function createTenantClientPool<TClient extends DatabaseClient>(config: TenantClientPoolConfig<TClient>): ITenantClientPool<TClient>;
35
- /**
36
- * Type alias for the client pool
37
- */
38
- export type { ITenantClientPool as TenantClientPool };
@@ -53,23 +53,7 @@
53
53
  // ============================================================================
54
54
  // Errors
55
55
  // ============================================================================
56
- export { ClientCreateError, ClientDisconnectError,
57
- // Client pool errors
58
- ClientPoolExhaustedError, DeprovisionError, getTenantStatusError,
59
- // Validation errors
60
- InvalidSlugError,
61
- // Utilities
62
- isTenantError,
63
- // Provisioning errors
64
- ProvisionError, SchemaAlreadyExistsError,
65
- // Schema errors
66
- SchemaCreateError, SchemaDeleteError, SchemaListError, SchemaMigrateError, SchemaNotFoundError,
67
- // Authorization error
68
- TenantAccessDeniedError,
69
- // Base error
70
- TenantError, TenantIdMissingError, TenantMigratingError,
71
- // Tenant errors
72
- TenantNotFoundError, TenantPendingError, TenantSuspendedError, } from './errors.js';
56
+ export { ClientCreateError, ClientDisconnectError, ClientPoolExhaustedError, DeprovisionError, getTenantStatusError, InvalidSlugError, isTenantError, ProvisionError, SchemaAlreadyExistsError, SchemaCreateError, SchemaDeleteError, SchemaListError, SchemaMigrateError, SchemaNotFoundError, TenantAccessDeniedError, TenantError, TenantIdMissingError, TenantMigratingError, TenantNotFoundError, TenantPendingError, TenantSuspendedError, } from './errors.js';
73
57
  // ============================================================================
74
58
  // Client Pool
75
59
  // ============================================================================
@@ -64,13 +64,14 @@ export function createTenantMiddleware(config) {
64
64
  }
65
65
  // Get tenant-scoped database client
66
66
  const db = await clientPool.getClient(tenant.schemaName);
67
- // Build extended context
68
67
  const extendedCtx = {
69
68
  ...ctx,
70
69
  tenant,
71
70
  db,
72
- ...(publicClient ? { publicDb: publicClient } : {}),
73
71
  };
72
+ if (publicClient) {
73
+ extendedCtx.publicDb = publicClient;
74
+ }
74
75
  try {
75
76
  // Continue to next middleware/handler
76
77
  return await next({ ctx: extendedCtx });
@@ -44,25 +44,34 @@ const RESERVED_SCHEMAS = new Set([
44
44
  'pg_temp',
45
45
  'information_schema',
46
46
  ]);
47
+ /**
48
+ * Patterns that indicate dangerous input (SQL injection, shell injection, path traversal)
49
+ */
50
+ const DANGEROUS_PATTERNS = [
51
+ /[;|&$`<>]/, // Shell metacharacters
52
+ /['"`]/, // SQL quotes
53
+ /\0/, // Null bytes
54
+ /\.\./, // Path traversal
55
+ /[\\/]/, // Path separators
56
+ ];
47
57
  /**
48
58
  * Validate database URL format and check for injection patterns
49
59
  */
50
60
  function validateDatabaseUrl(url) {
61
+ let parsed;
51
62
  try {
52
- const parsed = new URL(url);
53
- // Only allow postgresql:// protocol
54
- if (parsed.protocol !== 'postgresql:' && parsed.protocol !== 'postgres:') {
55
- throw new Error('Invalid database protocol');
56
- }
57
- // Check for shell metacharacters
58
- const DANGEROUS_CHARS = /[;|&$`<>(){}[\]!]/;
59
- if (DANGEROUS_CHARS.test(url)) {
60
- throw new Error('Database URL contains dangerous characters');
61
- }
63
+ parsed = new URL(url);
62
64
  }
63
65
  catch {
64
66
  throw new Error('Invalid database URL format');
65
67
  }
68
+ if (parsed.protocol !== 'postgresql:' && parsed.protocol !== 'postgres:') {
69
+ throw new Error('Invalid database protocol');
70
+ }
71
+ const DANGEROUS_CHARS = /[;|&$`<>(){}[\]!]/;
72
+ if (DANGEROUS_CHARS.test(url)) {
73
+ throw new Error('Database URL contains dangerous characters');
74
+ }
66
75
  }
67
76
  /**
68
77
  * Validate Prisma schema path to prevent path traversal
@@ -168,14 +177,6 @@ export function createTenantSchemaManager(config) {
168
177
  if (!VALID_SLUG_REGEX.test(slug)) {
169
178
  throw new InvalidSlugError(slug, 'slug must contain only lowercase letters, numbers, and hyphens');
170
179
  }
171
- // Check for dangerous patterns
172
- const DANGEROUS_PATTERNS = [
173
- /[;|&$`<>]/, // Shell metacharacters
174
- /['"`]/, // SQL quotes
175
- /\0/, // Null bytes
176
- /\.\./, // Path traversal
177
- /[\\/]/, // Path separators
178
- ];
179
180
  for (const pattern of DANGEROUS_PATTERNS) {
180
181
  if (pattern.test(slug)) {
181
182
  throw new InvalidSlugError(slug, 'slug contains forbidden characters');
@@ -205,8 +206,6 @@ export function createTenantSchemaManager(config) {
205
206
  if (RESERVED_SCHEMAS.has(schemaName.toLowerCase())) {
206
207
  throw new Error(`Cannot use reserved schema name: ${schemaName}`);
207
208
  }
208
- // Additional security checks
209
- const DANGEROUS_PATTERNS = [/[;|&$`<>]/, /['"`]/, /\0/, /\.\./, /[\\/]/];
210
209
  for (const pattern of DANGEROUS_PATTERNS) {
211
210
  if (pattern.test(schemaName)) {
212
211
  throw new Error(`Schema name contains forbidden characters: ${schemaName}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veloxts/orm",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Prisma wrapper with enhanced DX for VeloxTS framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,7 +19,7 @@
19
19
  "fastify": "5.7.4",
20
20
  "pg": "8.18.0",
21
21
  "pg-format": "1.0.4",
22
- "@veloxts/core": "0.7.0"
22
+ "@veloxts/core": "0.7.2"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/pg": "8.16.0",