@freshguard/freshguard-core 0.13.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/README.md +74 -1
  3. package/SKILL.md +229 -0
  4. package/dist/cli/index.d.ts +13 -0
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +74 -1
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/connectors/azure-sql.d.ts +121 -0
  9. package/dist/connectors/azure-sql.d.ts.map +1 -0
  10. package/dist/connectors/azure-sql.js +489 -0
  11. package/dist/connectors/azure-sql.js.map +1 -0
  12. package/dist/connectors/base-connector.d.ts +139 -0
  13. package/dist/connectors/base-connector.d.ts.map +1 -1
  14. package/dist/connectors/base-connector.js +160 -3
  15. package/dist/connectors/base-connector.js.map +1 -1
  16. package/dist/connectors/bigquery.d.ts +100 -0
  17. package/dist/connectors/bigquery.d.ts.map +1 -1
  18. package/dist/connectors/bigquery.js +143 -2
  19. package/dist/connectors/bigquery.js.map +1 -1
  20. package/dist/connectors/duckdb.d.ts +96 -0
  21. package/dist/connectors/duckdb.d.ts.map +1 -1
  22. package/dist/connectors/duckdb.js +144 -7
  23. package/dist/connectors/duckdb.js.map +1 -1
  24. package/dist/connectors/index.d.ts +28 -0
  25. package/dist/connectors/index.d.ts.map +1 -1
  26. package/dist/connectors/index.js +28 -0
  27. package/dist/connectors/index.js.map +1 -1
  28. package/dist/connectors/mssql.d.ts +119 -0
  29. package/dist/connectors/mssql.d.ts.map +1 -0
  30. package/dist/connectors/mssql.js +483 -0
  31. package/dist/connectors/mssql.js.map +1 -0
  32. package/dist/connectors/mysql.d.ts +85 -0
  33. package/dist/connectors/mysql.d.ts.map +1 -1
  34. package/dist/connectors/mysql.js +118 -3
  35. package/dist/connectors/mysql.js.map +1 -1
  36. package/dist/connectors/postgres.d.ts +85 -0
  37. package/dist/connectors/postgres.d.ts.map +1 -1
  38. package/dist/connectors/postgres.js +113 -6
  39. package/dist/connectors/postgres.js.map +1 -1
  40. package/dist/connectors/redshift.d.ts +90 -0
  41. package/dist/connectors/redshift.d.ts.map +1 -1
  42. package/dist/connectors/redshift.js +131 -7
  43. package/dist/connectors/redshift.js.map +1 -1
  44. package/dist/connectors/snowflake.d.ts +108 -0
  45. package/dist/connectors/snowflake.d.ts.map +1 -1
  46. package/dist/connectors/snowflake.js +137 -3
  47. package/dist/connectors/snowflake.js.map +1 -1
  48. package/dist/connectors/synapse.d.ts +123 -0
  49. package/dist/connectors/synapse.d.ts.map +1 -0
  50. package/dist/connectors/synapse.js +495 -0
  51. package/dist/connectors/synapse.js.map +1 -0
  52. package/dist/db/index.d.ts +25 -0
  53. package/dist/db/index.d.ts.map +1 -1
  54. package/dist/db/index.js +23 -0
  55. package/dist/db/index.js.map +1 -1
  56. package/dist/db/migrate.d.ts +23 -0
  57. package/dist/db/migrate.d.ts.map +1 -1
  58. package/dist/db/migrate.js +38 -0
  59. package/dist/db/migrate.js.map +1 -1
  60. package/dist/db/schema.d.ts +11 -0
  61. package/dist/db/schema.d.ts.map +1 -1
  62. package/dist/db/schema.js +70 -0
  63. package/dist/db/schema.js.map +1 -1
  64. package/dist/errors/debug-factory.d.ts +38 -0
  65. package/dist/errors/debug-factory.d.ts.map +1 -1
  66. package/dist/errors/debug-factory.js +40 -0
  67. package/dist/errors/debug-factory.js.map +1 -1
  68. package/dist/errors/index.d.ts +59 -0
  69. package/dist/errors/index.d.ts.map +1 -1
  70. package/dist/errors/index.js +110 -7
  71. package/dist/errors/index.js.map +1 -1
  72. package/dist/index.d.ts +32 -1
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +37 -1
  75. package/dist/index.js.map +1 -1
  76. package/dist/metadata/duckdb-storage.d.ts +3 -0
  77. package/dist/metadata/duckdb-storage.d.ts.map +1 -1
  78. package/dist/metadata/duckdb-storage.js +6 -0
  79. package/dist/metadata/duckdb-storage.js.map +1 -1
  80. package/dist/metadata/factory.d.ts +30 -0
  81. package/dist/metadata/factory.d.ts.map +1 -1
  82. package/dist/metadata/factory.js +31 -0
  83. package/dist/metadata/factory.js.map +1 -1
  84. package/dist/metadata/index.d.ts +26 -0
  85. package/dist/metadata/index.d.ts.map +1 -1
  86. package/dist/metadata/index.js +26 -0
  87. package/dist/metadata/index.js.map +1 -1
  88. package/dist/metadata/interface.d.ts +33 -0
  89. package/dist/metadata/interface.d.ts.map +1 -1
  90. package/dist/metadata/interface.js +3 -0
  91. package/dist/metadata/interface.js.map +1 -1
  92. package/dist/metadata/postgresql-storage.d.ts +3 -0
  93. package/dist/metadata/postgresql-storage.d.ts.map +1 -1
  94. package/dist/metadata/postgresql-storage.js +12 -2
  95. package/dist/metadata/postgresql-storage.js.map +1 -1
  96. package/dist/metadata/schema-config.d.ts +53 -0
  97. package/dist/metadata/schema-config.d.ts.map +1 -1
  98. package/dist/metadata/schema-config.js +64 -0
  99. package/dist/metadata/schema-config.js.map +1 -1
  100. package/dist/metadata/types.d.ts +3 -0
  101. package/dist/metadata/types.d.ts.map +1 -1
  102. package/dist/metadata/types.js +3 -0
  103. package/dist/metadata/types.js.map +1 -1
  104. package/dist/monitor/baseline-calculator.d.ts +56 -0
  105. package/dist/monitor/baseline-calculator.d.ts.map +1 -1
  106. package/dist/monitor/baseline-calculator.js +72 -0
  107. package/dist/monitor/baseline-calculator.js.map +1 -1
  108. package/dist/monitor/baseline-config.d.ts +77 -0
  109. package/dist/monitor/baseline-config.d.ts.map +1 -1
  110. package/dist/monitor/baseline-config.js +79 -1
  111. package/dist/monitor/baseline-config.js.map +1 -1
  112. package/dist/monitor/freshness.d.ts +40 -0
  113. package/dist/monitor/freshness.d.ts.map +1 -1
  114. package/dist/monitor/freshness.js +82 -3
  115. package/dist/monitor/freshness.js.map +1 -1
  116. package/dist/monitor/index.d.ts +29 -0
  117. package/dist/monitor/index.d.ts.map +1 -1
  118. package/dist/monitor/index.js +29 -0
  119. package/dist/monitor/index.js.map +1 -1
  120. package/dist/monitor/schema-baseline.d.ts +45 -0
  121. package/dist/monitor/schema-baseline.d.ts.map +1 -1
  122. package/dist/monitor/schema-baseline.js +63 -5
  123. package/dist/monitor/schema-baseline.js.map +1 -1
  124. package/dist/monitor/schema-changes.d.ts +45 -0
  125. package/dist/monitor/schema-changes.d.ts.map +1 -1
  126. package/dist/monitor/schema-changes.js +85 -0
  127. package/dist/monitor/schema-changes.js.map +1 -1
  128. package/dist/monitor/volume.d.ts +43 -0
  129. package/dist/monitor/volume.d.ts.map +1 -1
  130. package/dist/monitor/volume.js +89 -0
  131. package/dist/monitor/volume.js.map +1 -1
  132. package/dist/observability/logger.d.ts +91 -0
  133. package/dist/observability/logger.d.ts.map +1 -1
  134. package/dist/observability/logger.js +108 -0
  135. package/dist/observability/logger.js.map +1 -1
  136. package/dist/observability/metrics.d.ts +140 -0
  137. package/dist/observability/metrics.d.ts.map +1 -1
  138. package/dist/observability/metrics.js +184 -7
  139. package/dist/observability/metrics.js.map +1 -1
  140. package/dist/resilience/circuit-breaker.d.ts +112 -2
  141. package/dist/resilience/circuit-breaker.d.ts.map +1 -1
  142. package/dist/resilience/circuit-breaker.js +140 -6
  143. package/dist/resilience/circuit-breaker.js.map +1 -1
  144. package/dist/resilience/index.d.ts +9 -0
  145. package/dist/resilience/index.d.ts.map +1 -1
  146. package/dist/resilience/index.js +13 -0
  147. package/dist/resilience/index.js.map +1 -1
  148. package/dist/resilience/retry-policy.d.ts +105 -0
  149. package/dist/resilience/retry-policy.d.ts.map +1 -1
  150. package/dist/resilience/retry-policy.js +158 -7
  151. package/dist/resilience/retry-policy.js.map +1 -1
  152. package/dist/resilience/timeout-manager.d.ts +137 -0
  153. package/dist/resilience/timeout-manager.d.ts.map +1 -1
  154. package/dist/resilience/timeout-manager.js +151 -4
  155. package/dist/resilience/timeout-manager.js.map +1 -1
  156. package/dist/security/query-analyzer.d.ts +124 -0
  157. package/dist/security/query-analyzer.d.ts.map +1 -1
  158. package/dist/security/query-analyzer.js +150 -9
  159. package/dist/security/query-analyzer.js.map +1 -1
  160. package/dist/security/schema-cache.d.ts +152 -0
  161. package/dist/security/schema-cache.d.ts.map +1 -1
  162. package/dist/security/schema-cache.js +144 -12
  163. package/dist/security/schema-cache.js.map +1 -1
  164. package/dist/types/connector.d.ts +68 -1
  165. package/dist/types/connector.d.ts.map +1 -1
  166. package/dist/types/connector.js +38 -15
  167. package/dist/types/connector.js.map +1 -1
  168. package/dist/types/driver-results.d.ts +28 -0
  169. package/dist/types/driver-results.d.ts.map +1 -1
  170. package/dist/types/driver-results.js +12 -0
  171. package/dist/types/driver-results.js.map +1 -1
  172. package/dist/types.d.ts +113 -1
  173. package/dist/types.d.ts.map +1 -1
  174. package/dist/types.js +8 -0
  175. package/dist/types.js.map +1 -1
  176. package/dist/validation/index.d.ts +8 -0
  177. package/dist/validation/index.d.ts.map +1 -1
  178. package/dist/validation/index.js +12 -0
  179. package/dist/validation/index.js.map +1 -1
  180. package/dist/validation/runtime-validator.d.ts +98 -0
  181. package/dist/validation/runtime-validator.d.ts.map +1 -1
  182. package/dist/validation/runtime-validator.js +114 -1
  183. package/dist/validation/runtime-validator.js.map +1 -1
  184. package/dist/validation/sanitizers.d.ts +59 -0
  185. package/dist/validation/sanitizers.d.ts.map +1 -1
  186. package/dist/validation/sanitizers.js +104 -20
  187. package/dist/validation/sanitizers.js.map +1 -1
  188. package/dist/validation/schemas.d.ts +73 -0
  189. package/dist/validation/schemas.d.ts.map +1 -1
  190. package/dist/validation/schemas.js +132 -5
  191. package/dist/validation/schemas.js.map +1 -1
  192. package/dist/validators/index.d.ts +54 -0
  193. package/dist/validators/index.d.ts.map +1 -1
  194. package/dist/validators/index.js +93 -2
  195. package/dist/validators/index.js.map +1 -1
  196. package/package.json +6 -2
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Secure Microsoft SQL Server connector for FreshGuard Core
3
+ * Extends BaseConnector with security built-in
4
+ *
5
+ * @module @freshguard/freshguard-core/connectors/mssql
6
+ */
7
+ import { BaseConnector } from './base-connector.js';
8
+ import type { ConnectorConfig, TableSchema, SecurityConfig } from '../types/connector.js';
9
+ import { type QueryResultRow } from '../types/driver-results.js';
10
+ import type { SourceCredentials } from '../types.js';
11
+ /**
12
+ * Secure SQL Server connector
13
+ *
14
+ * Features:
15
+ * - SQL injection prevention
16
+ * - Connection timeouts
17
+ * - SSL enforcement
18
+ * - Read-only query patterns
19
+ * - Secure error handling
20
+ * - Connection pooling via mssql
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { MSSQLConnector } from '@freshguard/freshguard-core';
25
+ *
26
+ * const connector = new MSSQLConnector({
27
+ * host: 'sql-server.example.com', port: 1433,
28
+ * database: 'analytics',
29
+ * username: 'readonly',
30
+ * password: process.env.MSSQL_PASSWORD!,
31
+ * ssl: true,
32
+ * });
33
+ * ```
34
+ */
35
+ export declare class MSSQLConnector extends BaseConnector {
36
+ private pool;
37
+ private connected;
38
+ /**
39
+ * @param config - Database connection settings (host, port, database, credentials)
40
+ * @param securityConfig - Optional overrides for query timeouts, max rows, SSL, and blocked keywords
41
+ */
42
+ constructor(config: ConnectorConfig, securityConfig?: Partial<SecurityConfig>);
43
+ /**
44
+ * Connect to SQL Server database with security validation
45
+ */
46
+ private connect;
47
+ /**
48
+ * Execute a validated SQL query with security measures
49
+ */
50
+ protected executeQuery(sql: string): Promise<QueryResultRow[]>;
51
+ /**
52
+ * Execute a parameterized SQL query using prepared statements
53
+ */
54
+ protected executeParameterizedQuery(sql: string, parameters?: unknown[]): Promise<QueryResultRow[]>;
55
+ /**
56
+ * Test database connection with security validation
57
+ */
58
+ testConnection(debugConfig?: import('../types.js').DebugConfig): Promise<boolean>;
59
+ /**
60
+ * Helper method to merge debug configuration
61
+ */
62
+ private mergeDebugConfig;
63
+ /**
64
+ * Generate connection suggestions based on error
65
+ */
66
+ private generateConnectionSuggestion;
67
+ /**
68
+ * List all tables in the database
69
+ */
70
+ listTables(): Promise<string[]>;
71
+ /**
72
+ * Get table schema information securely
73
+ */
74
+ getTableSchema(table: string): Promise<TableSchema>;
75
+ /**
76
+ * Get last modified timestamp using SQL Server-specific methods
77
+ */
78
+ getLastModified(table: string): Promise<Date | null>;
79
+ /**
80
+ * Close the database connection
81
+ */
82
+ close(): Promise<void>;
83
+ /**
84
+ * Map SQL Server data types to standard types
85
+ */
86
+ private mapMSSQLType;
87
+ /**
88
+ * Override escapeIdentifier for SQL Server bracket notation
89
+ */
90
+ protected escapeIdentifier(identifier: string): string;
91
+ /**
92
+ * Legacy connect method for backward compatibility
93
+ * @deprecated Use constructor with ConnectorConfig instead
94
+ */
95
+ connectLegacy(credentials: SourceCredentials): Promise<void>;
96
+ /**
97
+ * Legacy test connection method for backward compatibility
98
+ * @deprecated Use testConnection() instead
99
+ */
100
+ testConnectionLegacy(): Promise<{
101
+ success: boolean;
102
+ tableCount?: number;
103
+ error?: string;
104
+ }>;
105
+ /**
106
+ * Legacy get table metadata method for backward compatibility
107
+ * @deprecated Use getRowCount() and getMaxTimestamp() instead
108
+ */
109
+ getTableMetadata(tableName: string, timestampColumn?: string): Promise<{
110
+ rowCount: number;
111
+ lastUpdate?: Date;
112
+ }>;
113
+ /**
114
+ * Legacy query method for backward compatibility
115
+ * @deprecated Direct SQL queries are not allowed for security reasons
116
+ */
117
+ query<T = unknown>(_sql: string): Promise<T[]>;
118
+ }
119
+ //# sourceMappingURL=mssql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mssql.d.ts","sourceRoot":"","sources":["../../src/connectors/mssql.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,EAAE,KAAK,cAAc,EAAa,MAAM,4BAA4B,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASrD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,cAAe,SAAQ,aAAa;IAC/C,OAAO,CAAC,IAAI,CAAqC;IACjD,OAAO,CAAC,SAAS,CAAS;IAE1B;;;OAGG;gBACS,MAAM,EAAE,eAAe,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAM7E;;OAEG;YACW,OAAO;IAwCrB;;OAEG;cACa,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAIpE;;OAEG;cACa,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAoD7G;;OAEG;IACG,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,aAAa,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAgEvF;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAkCpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IA2BrC;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA+CzD;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAsC1D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAmDpB;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAmBtD;;;OAGG;IACG,aAAa,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlE;;;OAGG;IACG,oBAAoB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA2BhG;;;OAGG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAe,GAC7B,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC;IAqBnD;;;OAGG;IAEG,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;CAKrD"}
@@ -0,0 +1,483 @@
1
+ /**
2
+ * Secure Microsoft SQL Server connector for FreshGuard Core
3
+ * Extends BaseConnector with security built-in
4
+ *
5
+ * @module @freshguard/freshguard-core/connectors/mssql
6
+ */
7
+ import * as mssql from 'mssql';
8
+ import { BaseConnector } from './base-connector.js';
9
+ import { rowString } from '../types/driver-results.js';
10
+ import { ConnectionError, TimeoutError, QueryError, ErrorHandler } from '../errors/index.js';
11
+ import { validateConnectorConfig } from '../validators/index.js';
12
+ /**
13
+ * Secure SQL Server connector
14
+ *
15
+ * Features:
16
+ * - SQL injection prevention
17
+ * - Connection timeouts
18
+ * - SSL enforcement
19
+ * - Read-only query patterns
20
+ * - Secure error handling
21
+ * - Connection pooling via mssql
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { MSSQLConnector } from '@freshguard/freshguard-core';
26
+ *
27
+ * const connector = new MSSQLConnector({
28
+ * host: 'sql-server.example.com', port: 1433,
29
+ * database: 'analytics',
30
+ * username: 'readonly',
31
+ * password: process.env.MSSQL_PASSWORD!,
32
+ * ssl: true,
33
+ * });
34
+ * ```
35
+ */
36
+ export class MSSQLConnector extends BaseConnector {
37
+ pool = null;
38
+ connected = false;
39
+ /**
40
+ * @param config - Database connection settings (host, port, database, credentials)
41
+ * @param securityConfig - Optional overrides for query timeouts, max rows, SSL, and blocked keywords
42
+ */
43
+ constructor(config, securityConfig) {
44
+ // Validate configuration before proceeding
45
+ validateConnectorConfig(config);
46
+ super(config, securityConfig);
47
+ }
48
+ /**
49
+ * Connect to SQL Server database with security validation
50
+ */
51
+ async connect() {
52
+ if (this.connected && this.pool) {
53
+ return; // Already connected
54
+ }
55
+ try {
56
+ const poolConfig = {
57
+ server: this.config.host,
58
+ port: this.config.port ?? 1433,
59
+ database: this.config.database,
60
+ user: this.config.username,
61
+ password: this.config.password,
62
+ options: {
63
+ encrypt: this.requireSSL || this.config.ssl !== false,
64
+ trustServerCertificate: false,
65
+ connectTimeout: this.connectionTimeout,
66
+ requestTimeout: this.queryTimeout,
67
+ appName: this.config.applicationName ?? 'freshguard-core'
68
+ },
69
+ pool: {
70
+ max: 1, // Single connection for monitoring
71
+ min: 0,
72
+ idleTimeoutMillis: 30000
73
+ }
74
+ };
75
+ this.pool = new mssql.ConnectionPool(poolConfig);
76
+ await this.pool.connect();
77
+ this.connected = true;
78
+ }
79
+ catch (error) {
80
+ throw new ConnectionError('Failed to connect to SQL Server', this.config.host, this.config.port, error instanceof Error ? error : undefined);
81
+ }
82
+ }
83
+ /**
84
+ * Execute a validated SQL query with security measures
85
+ */
86
+ async executeQuery(sql) {
87
+ return this.executeParameterizedQuery(sql, []);
88
+ }
89
+ /**
90
+ * Execute a parameterized SQL query using prepared statements
91
+ */
92
+ async executeParameterizedQuery(sql, parameters = []) {
93
+ await this.connect();
94
+ if (!this.pool) {
95
+ throw new ConnectionError('Database connection not available');
96
+ }
97
+ try {
98
+ const result = await this.executeWithTimeout(async () => {
99
+ if (!this.pool)
100
+ throw new ConnectionError('Database connection not available');
101
+ const request = this.pool.request();
102
+ // Bind positional parameters as @p1, @p2, etc.
103
+ for (let i = 0; i < parameters.length; i++) {
104
+ request.input(`p${i + 1}`, parameters[i]);
105
+ }
106
+ // Replace $N placeholders with @pN for MSSQL
107
+ let mssqlSql = sql;
108
+ for (let i = parameters.length; i >= 1; i--) {
109
+ mssqlSql = mssqlSql.replace(new RegExp(`\\$${i}`, 'g'), `@p${i}`);
110
+ }
111
+ // Also replace ? placeholders with @pN
112
+ let paramIndex = 0;
113
+ mssqlSql = mssqlSql.replace(/\?/g, () => `@p${++paramIndex}`);
114
+ const res = await request.query(mssqlSql);
115
+ return (res.recordset ?? []);
116
+ }, this.queryTimeout);
117
+ // Validate result size for security
118
+ this.validateResultSize(result);
119
+ return result;
120
+ }
121
+ catch (error) {
122
+ if (error instanceof TimeoutError) {
123
+ throw error;
124
+ }
125
+ // Sanitize and re-throw as QueryError
126
+ throw new QueryError(ErrorHandler.getUserMessage(error), 'query_execution', undefined, error instanceof Error ? error : undefined);
127
+ }
128
+ }
129
+ /**
130
+ * Test database connection with security validation
131
+ */
132
+ async testConnection(debugConfig) {
133
+ const mergedDebugConfig = this.mergeDebugConfig(debugConfig);
134
+ const debugId = `mssql-test-${Date.now().toString(36)}-${Math.random().toString(36).substr(2, 5)}`;
135
+ const startTime = performance.now();
136
+ try {
137
+ this.logDebugInfo(mergedDebugConfig, debugId, 'Starting connection test', {
138
+ host: this.config.host,
139
+ port: this.config.port,
140
+ database: this.config.database,
141
+ ssl: this.config.ssl
142
+ });
143
+ await this.connect();
144
+ if (!this.pool) {
145
+ this.logDebugError(mergedDebugConfig, debugId, 'Connection test', {
146
+ error: 'Connection not available after connect',
147
+ duration: performance.now() - startTime
148
+ });
149
+ return false;
150
+ }
151
+ // Test with a simple, safe query (skip validation for connection test)
152
+ const sql = 'SELECT 1 AS test';
153
+ await this.executeWithTimeout(async () => {
154
+ if (!this.pool)
155
+ throw new ConnectionError('Database connection not available');
156
+ const request = this.pool.request();
157
+ return request.query(sql);
158
+ }, this.connectionTimeout);
159
+ const duration = performance.now() - startTime;
160
+ if (mergedDebugConfig?.enabled) {
161
+ console.log(`[DEBUG-${debugId}] Connection test completed:`, {
162
+ success: true,
163
+ duration,
164
+ host: this.config.host,
165
+ database: this.config.database
166
+ });
167
+ }
168
+ return true;
169
+ }
170
+ catch (error) {
171
+ const duration = performance.now() - startTime;
172
+ this.logDebugError(mergedDebugConfig, debugId, 'Connection test', {
173
+ host: this.config.host,
174
+ port: this.config.port,
175
+ database: this.config.database,
176
+ error: mergedDebugConfig?.exposeRawErrors && error instanceof Error ? error.message : 'Connection failed',
177
+ duration,
178
+ suggestion: this.generateConnectionSuggestion(error)
179
+ });
180
+ // Don't throw - this method should return boolean
181
+ return false;
182
+ }
183
+ }
184
+ /**
185
+ * Helper method to merge debug configuration
186
+ */
187
+ mergeDebugConfig(debugConfig) {
188
+ return {
189
+ enabled: debugConfig?.enabled ?? (process.env.NODE_ENV === 'development'),
190
+ exposeQueries: debugConfig?.exposeQueries ?? true,
191
+ exposeRawErrors: debugConfig?.exposeRawErrors ?? true,
192
+ logLevel: debugConfig?.logLevel ?? 'debug'
193
+ };
194
+ }
195
+ /**
196
+ * Generate connection suggestions based on error
197
+ */
198
+ generateConnectionSuggestion(error) {
199
+ if (!(error instanceof Error)) {
200
+ return 'Check database connection configuration';
201
+ }
202
+ const message = error.message.toLowerCase();
203
+ if (message.includes('connect econnrefused') || message.includes('connection refused')) {
204
+ return `SQL Server at ${this.config.host}:${this.config.port} is not accepting connections. Verify the server is running and TCP/IP protocol is enabled in SQL Server Configuration Manager.`;
205
+ }
206
+ if (message.includes('timeout') || message.includes('connect timeout')) {
207
+ return `Connection timeout to ${this.config.host}:${this.config.port}. Check network connectivity, firewall rules, and server responsiveness.`;
208
+ }
209
+ if (message.includes('login failed') || message.includes('authentication failed')) {
210
+ return `Authentication failed for database '${this.config.database}'. Verify username, password, and that SQL Server authentication is enabled.`;
211
+ }
212
+ if (message.includes('cannot open database') || message.includes('database') && message.includes('not exist')) {
213
+ return `Database '${this.config.database}' not found on server. Check database name and create if necessary.`;
214
+ }
215
+ if (message.includes('ssl') || message.includes('tls') || message.includes('encrypt')) {
216
+ return `SSL/TLS connection issue. Check SSL configuration and server certificate settings.`;
217
+ }
218
+ if (message.includes('named pipes') || message.includes('named instance')) {
219
+ return `Connection issue with named instance. Ensure SQL Server Browser service is running and use hostname\\instance format.`;
220
+ }
221
+ return `Connection failed to ${this.config.host}:${this.config.port}. Check host, port, credentials, and network connectivity.`;
222
+ }
223
+ /**
224
+ * List all tables in the database
225
+ */
226
+ async listTables() {
227
+ const sql = `
228
+ SELECT TABLE_NAME as table_name
229
+ FROM INFORMATION_SCHEMA.TABLES
230
+ WHERE TABLE_TYPE = 'BASE TABLE'
231
+ AND TABLE_SCHEMA = 'dbo'
232
+ ORDER BY TABLE_NAME
233
+ `;
234
+ await this.validateQuery(sql);
235
+ try {
236
+ const result = await this.executeQuery(sql);
237
+ return result
238
+ .slice(0, this.maxRows)
239
+ .map((row) => rowString(row.table_name ?? row.TABLE_NAME ?? row.tablename))
240
+ .filter(Boolean);
241
+ }
242
+ catch (error) {
243
+ throw new QueryError('Failed to list tables', 'table_listing', undefined, error instanceof Error ? error : undefined);
244
+ }
245
+ }
246
+ /**
247
+ * Get table schema information securely
248
+ */
249
+ async getTableSchema(table) {
250
+ // Validate table name (identifiers cannot be parameterized)
251
+ this.escapeIdentifier(table);
252
+ const sql = `
253
+ SELECT
254
+ COLUMN_NAME as column_name,
255
+ DATA_TYPE as data_type,
256
+ IS_NULLABLE as is_nullable
257
+ FROM INFORMATION_SCHEMA.COLUMNS
258
+ WHERE TABLE_SCHEMA = 'dbo'
259
+ AND TABLE_NAME = '${table}'
260
+ ORDER BY ORDINAL_POSITION
261
+ `;
262
+ await this.validateQuery(sql);
263
+ try {
264
+ const result = await this.executeQuery(sql);
265
+ const limited = result.slice(0, this.maxRows);
266
+ if (limited.length === 0) {
267
+ throw QueryError.tableNotFound(table);
268
+ }
269
+ return {
270
+ table,
271
+ columns: limited.map(row => ({
272
+ name: rowString(row.column_name ?? row.COLUMN_NAME),
273
+ type: this.mapMSSQLType(rowString(row.data_type ?? row.DATA_TYPE)),
274
+ nullable: (row.is_nullable ?? row.IS_NULLABLE) === 'YES'
275
+ }))
276
+ };
277
+ }
278
+ catch (error) {
279
+ if (error instanceof QueryError) {
280
+ throw error;
281
+ }
282
+ throw new QueryError('Failed to get table schema', 'schema_query', table, error instanceof Error ? error : undefined);
283
+ }
284
+ }
285
+ /**
286
+ * Get last modified timestamp using SQL Server-specific methods
287
+ */
288
+ async getLastModified(table) {
289
+ // Try common timestamp columns
290
+ const timestampColumns = ['updated_at', 'modified_at', 'last_modified', 'timestamp'];
291
+ for (const column of timestampColumns) {
292
+ try {
293
+ const result = await this.getMaxTimestamp(table, column);
294
+ if (result) {
295
+ return result;
296
+ }
297
+ }
298
+ catch {
299
+ // Column doesn't exist, try next one
300
+ continue;
301
+ }
302
+ }
303
+ // Fallback: use SQL Server DMV for index usage stats
304
+ try {
305
+ const sql = `
306
+ SELECT MAX(last_user_update) as last_modified
307
+ FROM sys.dm_db_index_usage_stats
308
+ WHERE database_id = DB_ID()
309
+ AND object_id = OBJECT_ID('dbo.${this.escapeIdentifier(table).replace(/\[|\]/g, '')}')
310
+ `;
311
+ await this.validateQuery(sql);
312
+ const result = await this.executeQuery(sql);
313
+ if (result.length > 0 && result[0]?.last_modified) {
314
+ return new Date(rowString(result[0].last_modified));
315
+ }
316
+ }
317
+ catch {
318
+ // DMV query failed, return null
319
+ }
320
+ return null;
321
+ }
322
+ /**
323
+ * Close the database connection
324
+ */
325
+ async close() {
326
+ if (this.pool) {
327
+ try {
328
+ await this.pool.close();
329
+ }
330
+ catch (error) {
331
+ // Log error but don't throw - closing should be safe
332
+ console.warn('Warning: Error closing SQL Server connection:', ErrorHandler.getUserMessage(error));
333
+ }
334
+ finally {
335
+ this.pool = null;
336
+ this.connected = false;
337
+ }
338
+ }
339
+ }
340
+ /**
341
+ * Map SQL Server data types to standard types
342
+ */
343
+ mapMSSQLType(mssqlType) {
344
+ const typeMap = {
345
+ // Numeric types
346
+ 'tinyint': 'integer',
347
+ 'smallint': 'integer',
348
+ 'int': 'integer',
349
+ 'integer': 'integer',
350
+ 'bigint': 'bigint',
351
+ 'decimal': 'decimal',
352
+ 'numeric': 'decimal',
353
+ 'money': 'decimal',
354
+ 'smallmoney': 'decimal',
355
+ 'float': 'float',
356
+ 'real': 'float',
357
+ 'bit': 'boolean',
358
+ // String types
359
+ 'char': 'text',
360
+ 'varchar': 'text',
361
+ 'text': 'text',
362
+ 'nchar': 'text',
363
+ 'nvarchar': 'text',
364
+ 'ntext': 'text',
365
+ // Date/time types
366
+ 'date': 'date',
367
+ 'time': 'time',
368
+ 'datetime': 'timestamp',
369
+ 'datetime2': 'timestamp',
370
+ 'smalldatetime': 'timestamp',
371
+ 'datetimeoffset': 'timestamptz',
372
+ // Binary types
373
+ 'binary': 'text',
374
+ 'varbinary': 'text',
375
+ 'image': 'text',
376
+ // Special types
377
+ 'uniqueidentifier': 'text',
378
+ 'xml': 'text',
379
+ 'sql_variant': 'text',
380
+ 'hierarchyid': 'text',
381
+ 'geometry': 'text',
382
+ 'geography': 'text',
383
+ 'timestamp': 'text', // SQL Server timestamp is a rowversion, not a date
384
+ 'rowversion': 'text'
385
+ };
386
+ return typeMap[mssqlType.toLowerCase()] ?? 'unknown';
387
+ }
388
+ /**
389
+ * Override escapeIdentifier for SQL Server bracket notation
390
+ */
391
+ escapeIdentifier(identifier) {
392
+ // Only allow alphanumeric, underscore, and dot (for schema.table)
393
+ if (!/^[a-zA-Z0-9_.]+$/.test(identifier)) {
394
+ throw new Error(`Invalid identifier: ${identifier}`);
395
+ }
396
+ // Additional length check
397
+ if (identifier.length > 256) {
398
+ throw new Error('Identifier too long');
399
+ }
400
+ // Return with brackets for SQL Server
401
+ return `[${identifier}]`;
402
+ }
403
+ // ==============================================
404
+ // Legacy API compatibility methods
405
+ // ==============================================
406
+ /**
407
+ * Legacy connect method for backward compatibility
408
+ * @deprecated Use constructor with ConnectorConfig instead
409
+ */
410
+ async connectLegacy(credentials) {
411
+ console.warn('Warning: connectLegacy is deprecated. Use constructor with ConnectorConfig instead.');
412
+ // Convert legacy credentials to new format
413
+ const config = {
414
+ host: credentials.host ?? '',
415
+ port: credentials.port ?? 1433,
416
+ database: credentials.database ?? '',
417
+ username: credentials.username ?? '',
418
+ password: credentials.password ?? '',
419
+ ssl: credentials.sslMode !== 'disable'
420
+ };
421
+ // Validate and reconnect
422
+ validateConnectorConfig(config);
423
+ this.config = { ...this.config, ...config };
424
+ await this.connect();
425
+ }
426
+ /**
427
+ * Legacy test connection method for backward compatibility
428
+ * @deprecated Use testConnection() instead
429
+ */
430
+ async testConnectionLegacy() {
431
+ console.warn('Warning: testConnectionLegacy is deprecated. Use testConnection() instead.');
432
+ try {
433
+ const success = await this.testConnection();
434
+ if (success) {
435
+ // Get table count for legacy compatibility
436
+ const tables = await this.listTables();
437
+ return {
438
+ success: true,
439
+ tableCount: tables.length
440
+ };
441
+ }
442
+ else {
443
+ return {
444
+ success: false,
445
+ error: 'Connection test failed'
446
+ };
447
+ }
448
+ }
449
+ catch (error) {
450
+ return {
451
+ success: false,
452
+ error: ErrorHandler.getUserMessage(error)
453
+ };
454
+ }
455
+ }
456
+ /**
457
+ * Legacy get table metadata method for backward compatibility
458
+ * @deprecated Use getRowCount() and getMaxTimestamp() instead
459
+ */
460
+ async getTableMetadata(tableName, timestampColumn = 'updated_at') {
461
+ console.warn('Warning: getTableMetadata is deprecated. Use getRowCount() and getMaxTimestamp() instead.');
462
+ try {
463
+ const rowCount = await this.getRowCount(tableName);
464
+ const lastUpdate = await this.getMaxTimestamp(tableName, timestampColumn);
465
+ return {
466
+ rowCount,
467
+ lastUpdate: lastUpdate ?? undefined
468
+ };
469
+ }
470
+ catch (error) {
471
+ throw new QueryError('Failed to get table metadata', 'metadata_query', tableName, error instanceof Error ? error : undefined);
472
+ }
473
+ }
474
+ /**
475
+ * Legacy query method for backward compatibility
476
+ * @deprecated Direct SQL queries are not allowed for security reasons
477
+ */
478
+ // eslint-disable-next-line @typescript-eslint/require-await -- deprecated stub that always throws
479
+ async query(_sql) {
480
+ throw new Error('Direct SQL queries are not allowed for security reasons. Use specific methods like getRowCount(), getMaxTimestamp(), etc.');
481
+ }
482
+ }
483
+ //# sourceMappingURL=mssql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mssql.js","sourceRoot":"","sources":["../../src/connectors/mssql.ts"],"names":[],"mappings":"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"}