@yunfanye/sql-proxy 1.4.3 → 1.5.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/README.md CHANGED
@@ -4,7 +4,7 @@ A lightweight SQL proxy server that accepts SQL queries via HTTP and executes th
4
4
 
5
5
  ## Features
6
6
 
7
- - **Multi-database support**: Connect to PostgreSQL, MySQL, or Snowflake
7
+ - **Multi-database support**: Connect to PostgreSQL, MySQL, Snowflake, or another sql-proxy instance
8
8
  - **HTTP API**: Execute SQL queries via simple HTTP requests
9
9
  - **Read-only by default**: Only SELECT queries allowed unless `--allow-write` is specified
10
10
  - **Table access control**: Configure disallowed tables to prevent access to sensitive data
@@ -87,11 +87,25 @@ The server reads configuration from `database_config.json` in the current workin
87
87
  }
88
88
  ```
89
89
 
90
+ ### SQL Proxy (Chaining)
91
+
92
+ Connect to another sql-proxy instance for chaining proxies or accessing remote databases through a proxy:
93
+
94
+ ```json
95
+ {
96
+ "db_engine": "sql-proxy",
97
+ "disallowed_tables": [],
98
+ "db_credentials": {
99
+ "DB_URL": "http://localhost:3001"
100
+ }
101
+ }
102
+ ```
103
+
90
104
  ### Configuration Options
91
105
 
92
106
  | Field | Type | Required | Description |
93
107
  |-------|------|----------|-------------|
94
- | `db_engine` | string | Yes | Database engine: `postgresql`, `mysql`, or `snowsql` |
108
+ | `db_engine` | string | Yes | Database engine: `postgresql`, `mysql`, `snowsql`, or `sql-proxy` |
95
109
  | `disallowed_tables` | string[] | No | List of table names that cannot be queried |
96
110
  | `db_credentials` | object | Yes | Database connection credentials |
97
111
 
@@ -404,7 +418,7 @@ if (config) {
404
418
  ### DatabaseConfig Types
405
419
 
406
420
  ```typescript
407
- type DbEngine = 'postgresql' | 'mysql' | 'snowsql';
421
+ type DbEngine = 'postgresql' | 'mysql' | 'snowsql' | 'sql-proxy';
408
422
 
409
423
  interface StandardCredentials {
410
424
  DB_URL: string;
@@ -451,6 +465,15 @@ const snowflakeConfig: DatabaseConfig = {
451
465
  SNOWSQL_SCHEMA: 'PUBLIC'
452
466
  }
453
467
  };
468
+
469
+ // SQL Proxy (chaining to another sql-proxy instance)
470
+ const sqlProxyConfig: DatabaseConfig = {
471
+ db_engine: 'sql-proxy',
472
+ disallowed_tables: [],
473
+ db_credentials: {
474
+ DB_URL: 'http://localhost:3001'
475
+ }
476
+ };
454
477
  ```
455
478
 
456
479
  ### Using Low-Level Connectors
@@ -462,7 +485,8 @@ import {
462
485
  createConnector,
463
486
  PostgreSQLConnector,
464
487
  MySQLConnector,
465
- SnowflakeConnector
488
+ SnowflakeConnector,
489
+ SqlProxyConnector
466
490
  } from '@yunfanye/sql-proxy';
467
491
 
468
492
  // Using factory function
@@ -3,4 +3,5 @@ export declare function createConnector(config: DatabaseConfig): DatabaseConnect
3
3
  export { PostgreSQLConnector } from './postgresql';
4
4
  export { MySQLConnector } from './mysql';
5
5
  export { SnowflakeConnector } from './snowflake';
6
+ export { SqlProxyConnector } from './sql-proxy';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAuD,MAAM,UAAU,CAAC;AAKlH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,iBAAiB,CAWzE;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAuD,MAAM,UAAU,CAAC;AAMlH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,iBAAiB,CAazE;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SnowflakeConnector = exports.MySQLConnector = exports.PostgreSQLConnector = void 0;
3
+ exports.SqlProxyConnector = exports.SnowflakeConnector = exports.MySQLConnector = exports.PostgreSQLConnector = void 0;
4
4
  exports.createConnector = createConnector;
5
5
  const postgresql_1 = require("./postgresql");
6
6
  const mysql_1 = require("./mysql");
7
7
  const snowflake_1 = require("./snowflake");
8
+ const sql_proxy_1 = require("./sql-proxy");
8
9
  function createConnector(config) {
9
10
  switch (config.db_engine) {
10
11
  case 'postgresql':
@@ -13,6 +14,8 @@ function createConnector(config) {
13
14
  return new mysql_1.MySQLConnector(config.db_credentials);
14
15
  case 'snowsql':
15
16
  return new snowflake_1.SnowflakeConnector(config.db_credentials);
17
+ case 'sql-proxy':
18
+ return new sql_proxy_1.SqlProxyConnector(config.db_credentials);
16
19
  default:
17
20
  throw new Error(`Unsupported database engine: ${config.db_engine}`);
18
21
  }
@@ -23,4 +26,6 @@ var mysql_2 = require("./mysql");
23
26
  Object.defineProperty(exports, "MySQLConnector", { enumerable: true, get: function () { return mysql_2.MySQLConnector; } });
24
27
  var snowflake_2 = require("./snowflake");
25
28
  Object.defineProperty(exports, "SnowflakeConnector", { enumerable: true, get: function () { return snowflake_2.SnowflakeConnector; } });
29
+ var sql_proxy_2 = require("./sql-proxy");
30
+ Object.defineProperty(exports, "SqlProxyConnector", { enumerable: true, get: function () { return sql_proxy_2.SqlProxyConnector; } });
26
31
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":";;;AAKA,0CAWC;AAfD,6CAAmD;AACnD,mCAAyC;AACzC,2CAAiD;AAEjD,SAAgB,eAAe,CAAC,MAAsB;IACpD,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,KAAK,YAAY;YACf,OAAO,IAAI,gCAAmB,CAAC,MAAM,CAAC,cAAqC,CAAC,CAAC;QAC/E,KAAK,OAAO;YACV,OAAO,IAAI,sBAAc,CAAC,MAAM,CAAC,cAAqC,CAAC,CAAC;QAC1E,KAAK,SAAS;YACZ,OAAO,IAAI,8BAAkB,CAAC,MAAM,CAAC,cAAsC,CAAC,CAAC;QAC/E;YACE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED,2CAAmD;AAA1C,iHAAA,mBAAmB,OAAA;AAC5B,iCAAyC;AAAhC,uGAAA,cAAc,OAAA;AACvB,yCAAiD;AAAxC,+GAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":";;;AAMA,0CAaC;AAlBD,6CAAmD;AACnD,mCAAyC;AACzC,2CAAiD;AACjD,2CAAgD;AAEhD,SAAgB,eAAe,CAAC,MAAsB;IACpD,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,KAAK,YAAY;YACf,OAAO,IAAI,gCAAmB,CAAC,MAAM,CAAC,cAAqC,CAAC,CAAC;QAC/E,KAAK,OAAO;YACV,OAAO,IAAI,sBAAc,CAAC,MAAM,CAAC,cAAqC,CAAC,CAAC;QAC1E,KAAK,SAAS;YACZ,OAAO,IAAI,8BAAkB,CAAC,MAAM,CAAC,cAAsC,CAAC,CAAC;QAC/E,KAAK,WAAW;YACd,OAAO,IAAI,6BAAiB,CAAC,MAAM,CAAC,cAAqC,CAAC,CAAC;QAC7E;YACE,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED,2CAAmD;AAA1C,iHAAA,mBAAmB,OAAA;AAC5B,iCAAyC;AAAhC,uGAAA,cAAc,OAAA;AACvB,yCAAiD;AAAxC,+GAAA,kBAAkB,OAAA;AAC3B,yCAAgD;AAAvC,8GAAA,iBAAiB,OAAA"}
@@ -0,0 +1,11 @@
1
+ import { DatabaseConnector, QueryResult, StandardCredentials } from '../types';
2
+ export declare class SqlProxyConnector implements DatabaseConnector {
3
+ private baseUrl;
4
+ private connected;
5
+ constructor(credentials: StandardCredentials);
6
+ connect(): Promise<void>;
7
+ disconnect(): Promise<void>;
8
+ executeQuery(sql: string): Promise<QueryResult>;
9
+ listTables(): Promise<string[]>;
10
+ }
11
+ //# sourceMappingURL=sql-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-proxy.d.ts","sourceRoot":"","sources":["../../src/connectors/sql-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAe/E,qBAAa,iBAAkB,YAAW,iBAAiB;IACzD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAkB;gBAEvB,WAAW,EAAE,mBAAmB;IAKtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAoC/C,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CActC"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqlProxyConnector = void 0;
4
+ class SqlProxyConnector {
5
+ constructor(credentials) {
6
+ this.connected = false;
7
+ // Remove trailing slash if present
8
+ this.baseUrl = credentials.DB_URL.replace(/\/$/, '');
9
+ }
10
+ async connect() {
11
+ // Test the connection by hitting the health endpoint
12
+ const response = await fetch(`${this.baseUrl}/health`);
13
+ if (!response.ok) {
14
+ throw new Error(`Failed to connect to sql-proxy at ${this.baseUrl}: ${response.statusText}`);
15
+ }
16
+ this.connected = true;
17
+ }
18
+ async disconnect() {
19
+ this.connected = false;
20
+ }
21
+ async executeQuery(sql) {
22
+ if (!this.connected) {
23
+ return { success: false, error: 'Not connected to sql-proxy' };
24
+ }
25
+ try {
26
+ const response = await fetch(`${this.baseUrl}/query`, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ },
31
+ body: JSON.stringify({ sql }),
32
+ });
33
+ const result = await response.json();
34
+ if (result.success) {
35
+ return {
36
+ success: true,
37
+ data: result.data,
38
+ rowCount: result.rowCount,
39
+ };
40
+ }
41
+ else {
42
+ return {
43
+ success: false,
44
+ error: result.error,
45
+ };
46
+ }
47
+ }
48
+ catch (error) {
49
+ return {
50
+ success: false,
51
+ error: error.message,
52
+ };
53
+ }
54
+ }
55
+ async listTables() {
56
+ if (!this.connected) {
57
+ throw new Error('Not connected to sql-proxy');
58
+ }
59
+ const response = await fetch(`${this.baseUrl}/tables`);
60
+ const result = await response.json();
61
+ if (result.success && result.tables) {
62
+ return result.tables;
63
+ }
64
+ else {
65
+ throw new Error(result.error || 'Failed to list tables');
66
+ }
67
+ }
68
+ }
69
+ exports.SqlProxyConnector = SqlProxyConnector;
70
+ //# sourceMappingURL=sql-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-proxy.js","sourceRoot":"","sources":["../../src/connectors/sql-proxy.ts"],"names":[],"mappings":";;;AAeA,MAAa,iBAAiB;IAI5B,YAAY,WAAgC;QAFpC,cAAS,GAAY,KAAK,CAAC;QAGjC,mCAAmC;QACnC,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,qDAAqD;QACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qCAAqC,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;QACjE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,QAAQ,EAAE;gBACpD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;aAC9B,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA2B,CAAC;YAE9D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM,CAAC,KAAK;iBACpB,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,KAAK,CAAC,OAAO;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA4B,CAAC;QAE/D,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACpC,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF;AAxED,8CAwEC"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type DbEngine = 'postgresql' | 'mysql' | 'snowsql';
1
+ export type DbEngine = 'postgresql' | 'mysql' | 'snowsql' | 'sql-proxy';
2
2
  export interface SnowflakeCredentials {
3
3
  SNOWSQL_ACCOUNT: string;
4
4
  SNOWSQL_USER: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,QAAQ,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACjC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,QAAQ,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACjC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yunfanye/sql-proxy",
3
- "version": "1.4.3",
3
+ "version": "1.5.0",
4
4
  "description": "A SQL proxy server that accepts SQL queries via HTTP and executes them against configured database backends (PostgreSQL, MySQL, Snowflake)",
5
5
  "main": "dist/index.js",
6
6
  "bin": {