@forestadmin/datasource-sql 1.6.5 → 1.6.7

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.
@@ -0,0 +1,47 @@
1
+ import { Logger } from '@forestadmin/datasource-toolkit';
2
+ import { Dialect, Options as SequelizeOptions } from 'sequelize';
3
+ import { PlainConnectionOptions, PlainConnectionOptionsOrUri, ProxyOptions } from '../types';
4
+ /**
5
+ * Connection options.
6
+ * This wrapper is constructed from a plain object or a URI string.
7
+ *
8
+ * It is capable of parsing them, and providing an interface to the rest of the code to:
9
+ * - Build parameters to create sequelize instances
10
+ * - Build connections options with both dialect and sslmode resolved (for quick startup in cloud)
11
+ * - Provide safe urls for error messages (without credentials)
12
+ * - Play with the host and port without breaking SSL servername / error messages (for the proxy)
13
+ */
14
+ export default class ConnectionOptions {
15
+ proxyOptions?: ProxyOptions;
16
+ private initialHost;
17
+ private initialPort;
18
+ private logger?;
19
+ private sequelizeOptions;
20
+ private sslMode;
21
+ private uri?;
22
+ /**
23
+ * Database URI without credentials, which can be used in error messages.
24
+ * Ensure that this is never substituted by the proxy, nor that it includes credentials.
25
+ */
26
+ get debugDatabaseUri(): string;
27
+ /** Proxy URI without credentials, which can be used in error messages INTERNALLY */
28
+ get debugProxyUri(): string;
29
+ get dialect(): Dialect;
30
+ get host(): string;
31
+ get port(): number;
32
+ get database(): string;
33
+ constructor(options: PlainConnectionOptionsOrUri, logger?: Logger);
34
+ changeHostAndPort(host: string, port: number): void;
35
+ buildPreprocessedOptions(): Promise<PlainConnectionOptions>;
36
+ /** Options that can be passed to the sequelize constructor */
37
+ buildSequelizeCtorOptions(): Promise<[SequelizeOptions] | [string, SequelizeOptions]>;
38
+ private parseDatabaseUri;
39
+ /** Helper to fill the sequelize's options.schema */
40
+ private makeSequelizeSchema;
41
+ /** Helper to fill the sequelize's options.logging */
42
+ private makeSequelizeLogging;
43
+ /** Helper to fill the sequelize's options.dialectOptions */
44
+ private makeSequelizeDialectOptions;
45
+ private computeSslMode;
46
+ }
47
+ //# sourceMappingURL=connection-options.d.ts.map
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const errors_1 = require("./errors");
7
+ const index_1 = __importDefault(require("./index"));
8
+ /**
9
+ * Connection options.
10
+ * This wrapper is constructed from a plain object or a URI string.
11
+ *
12
+ * It is capable of parsing them, and providing an interface to the rest of the code to:
13
+ * - Build parameters to create sequelize instances
14
+ * - Build connections options with both dialect and sslmode resolved (for quick startup in cloud)
15
+ * - Provide safe urls for error messages (without credentials)
16
+ * - Play with the host and port without breaking SSL servername / error messages (for the proxy)
17
+ */
18
+ class ConnectionOptions {
19
+ /**
20
+ * Database URI without credentials, which can be used in error messages.
21
+ * Ensure that this is never substituted by the proxy, nor that it includes credentials.
22
+ */
23
+ get debugDatabaseUri() {
24
+ const dialect = this.dialect ?? '?';
25
+ const port = this.initialPort ?? '?';
26
+ const database = this.database ?? '?';
27
+ return dialect === 'sqlite'
28
+ ? this.uri?.href ?? `sqlite:${this.sequelizeOptions.storage}`
29
+ : `${dialect}://${this.initialHost}:${port}/${database}`;
30
+ }
31
+ /** Proxy URI without credentials, which can be used in error messages INTERNALLY */
32
+ get debugProxyUri() {
33
+ return this.proxyOptions ? `tcp://${this.proxyOptions.host}:${this.proxyOptions.port}` : 'none';
34
+ }
35
+ get dialect() {
36
+ let dialect = this.uri?.protocol?.slice(0, -1) || this.sequelizeOptions.dialect;
37
+ if (dialect === 'mysql2')
38
+ dialect = 'mysql';
39
+ else if (dialect === 'tedious')
40
+ dialect = 'mssql';
41
+ else if (dialect === 'pg' || dialect === 'postgresql')
42
+ dialect = 'postgres';
43
+ return dialect;
44
+ }
45
+ get host() {
46
+ return this.uri?.hostname ?? this.sequelizeOptions.host ?? 'localhost';
47
+ }
48
+ get port() {
49
+ let port = Number(this.uri?.port) || this.sequelizeOptions.port;
50
+ if (!port) {
51
+ // Use default port for known dialects otherwise
52
+ if (this.dialect === 'postgres')
53
+ port = 5432;
54
+ else if (this.dialect === 'mssql')
55
+ port = 1433;
56
+ else if (this.dialect === 'mysql' || this.dialect === 'mariadb')
57
+ port = 3306;
58
+ }
59
+ return port;
60
+ }
61
+ get database() {
62
+ return this.uri?.pathname?.slice(1) || this.sequelizeOptions.database;
63
+ }
64
+ constructor(options, logger) {
65
+ this.logger = logger;
66
+ if (typeof options === 'string') {
67
+ this.uri = this.parseDatabaseUri(options);
68
+ this.sequelizeOptions = {};
69
+ }
70
+ else {
71
+ const { uri, sslMode, proxySocks, ...sequelizeOptions } = options;
72
+ this.proxyOptions = proxySocks;
73
+ this.sequelizeOptions = sequelizeOptions;
74
+ this.sslMode = sslMode ?? 'manual';
75
+ this.uri = uri ? this.parseDatabaseUri(uri) : null;
76
+ }
77
+ // Save initial host & port (for SSL and error messages)
78
+ this.initialHost = this.host;
79
+ this.initialPort = this.port;
80
+ // Check required options
81
+ if (!this.dialect)
82
+ throw new errors_1.DatabaseConnectError(`Dialect is required`, this.debugDatabaseUri);
83
+ if (this.dialect !== 'sqlite' && !this.port)
84
+ throw new errors_1.DatabaseConnectError(`Port is required`, this.debugDatabaseUri);
85
+ }
86
+ changeHostAndPort(host, port) {
87
+ // Host
88
+ if (this.uri)
89
+ this.uri.hostname = host;
90
+ else
91
+ this.sequelizeOptions.host = host;
92
+ // Port
93
+ if (this.uri)
94
+ this.uri.port = String(port);
95
+ else
96
+ this.sequelizeOptions.port = port;
97
+ }
98
+ async buildPreprocessedOptions() {
99
+ const options = { ...this.sequelizeOptions };
100
+ if (this.uri)
101
+ options.uri = this.uri.toString();
102
+ if (this.proxyOptions)
103
+ options.proxySocks = this.proxyOptions;
104
+ options.dialect = this.dialect;
105
+ options.sslMode = await this.computeSslMode();
106
+ return options;
107
+ }
108
+ /** Options that can be passed to the sequelize constructor */
109
+ async buildSequelizeCtorOptions() {
110
+ const options = { ...this.sequelizeOptions };
111
+ options.dialect = this.dialect;
112
+ options.logging = this.makeSequelizeLogging();
113
+ options.schema = this.makeSequelizeSchema();
114
+ options.dialectOptions = {
115
+ ...(options.dialectOptions ?? {}),
116
+ ...(await this.makeSequelizeDialectOptions()),
117
+ };
118
+ return this.uri ? [this.uri.toString(), options] : [options];
119
+ }
120
+ parseDatabaseUri(str) {
121
+ const message = `Connection Uri "${str}" provided to SQL data source is not valid. ` +
122
+ `Should be <dialect>://<connection>.`;
123
+ if (!str.startsWith('sqlite') && !/.*:\/\//g.test(str))
124
+ throw new errors_1.DatabaseConnectError(message, str);
125
+ try {
126
+ return new URL(str);
127
+ }
128
+ catch {
129
+ throw new errors_1.DatabaseConnectError(message, str);
130
+ }
131
+ }
132
+ /** Helper to fill the sequelize's options.schema */
133
+ makeSequelizeSchema() {
134
+ return this.uri?.searchParams.get('schema') || this.sequelizeOptions.schema || null;
135
+ }
136
+ /** Helper to fill the sequelize's options.logging */
137
+ makeSequelizeLogging() {
138
+ return this.logger
139
+ ? (sql) => this.logger?.('Debug', sql.substring(sql.indexOf(':') + 2))
140
+ : false;
141
+ }
142
+ /** Helper to fill the sequelize's options.dialectOptions */
143
+ async makeSequelizeDialectOptions() {
144
+ const sslMode = await this.computeSslMode();
145
+ switch (this.dialect) {
146
+ case 'mariadb':
147
+ if (sslMode === 'disabled')
148
+ return { ssl: false };
149
+ if (sslMode === 'required')
150
+ return { ssl: { rejectUnauthorized: false } };
151
+ if (sslMode === 'verify')
152
+ return { ssl: true };
153
+ break;
154
+ case 'mssql':
155
+ if (sslMode === 'disabled')
156
+ return { options: { encrypt: false } };
157
+ if (sslMode === 'required')
158
+ return { options: { encrypt: true, trustServerCertificate: true } };
159
+ if (sslMode === 'verify')
160
+ return { options: { encrypt: true, trustServerCertificate: false } };
161
+ break;
162
+ case 'mysql':
163
+ if (sslMode === 'disabled')
164
+ return { ssl: false };
165
+ if (sslMode === 'required')
166
+ return { ssl: { rejectUnauthorized: false } };
167
+ if (sslMode === 'verify')
168
+ return { ssl: { rejectUnauthorized: true } };
169
+ break;
170
+ case 'postgres':
171
+ if (sslMode === 'disabled')
172
+ return { ssl: false };
173
+ // Pass servername to the net.tlsSocket constructor.
174
+ // This is done so that
175
+ // - Certificate verification still work when using a proxy server to reach the db (we are
176
+ // forced to use a tcp reverse proxy because some drivers do not support them)
177
+ // - Providers which use SNI to route requests to the correct database still work (most
178
+ // notably neon.tech).
179
+ // Note that we should either do that for the other vendors (if possible), or
180
+ // replace the reverse proxy by a forward proxy (when supported).
181
+ if (sslMode === 'required')
182
+ return {
183
+ ssl: { require: true, rejectUnauthorized: false, servername: this.initialHost },
184
+ };
185
+ if (sslMode === 'verify')
186
+ return { ssl: { require: true, rejectUnauthorized: true, servername: this.initialHost } };
187
+ break;
188
+ case 'db2':
189
+ case 'oracle':
190
+ case 'snowflake':
191
+ case 'sqlite':
192
+ default:
193
+ if (sslMode && sslMode !== 'manual') {
194
+ this.logger?.('Warn', `ignoring sslMode=${sslMode} (not supported for ${this.dialect})`);
195
+ }
196
+ return {};
197
+ }
198
+ }
199
+ async computeSslMode() {
200
+ if (this.sslMode !== 'preferred') {
201
+ return this.sslMode ?? 'manual';
202
+ }
203
+ // When NODE_TLS_REJECT_UNAUTHORIZED is set to 0, we skip the 'verify' mode, as we know it will
204
+ // always work locally, but not when deploying to another environment.
205
+ const modes = ['verify', 'required', 'disabled'];
206
+ if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0')
207
+ modes.shift();
208
+ let error;
209
+ for (const sslMode of modes) {
210
+ let sequelize;
211
+ try {
212
+ // eslint-disable-next-line no-await-in-loop
213
+ sequelize = await (0, index_1.default)(new ConnectionOptions({
214
+ uri: this.uri?.toString(),
215
+ sslMode,
216
+ ...this.sequelizeOptions,
217
+ }));
218
+ return sslMode;
219
+ }
220
+ catch (e) {
221
+ error = e;
222
+ }
223
+ finally {
224
+ await sequelize?.close(); // eslint-disable-line no-await-in-loop
225
+ }
226
+ }
227
+ throw error;
228
+ }
229
+ }
230
+ exports.default = ConnectionOptions;
231
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbi1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nvbm5lY3Rpb24vY29ubmVjdGlvbi1vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBR0EscUNBQWdEO0FBQ2hELG9EQUE4QjtBQVE5Qjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFxQixpQkFBaUI7SUFVcEM7OztPQUdHO0lBQ0gsSUFBSSxnQkFBZ0I7UUFDbEIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxHQUFHLENBQUM7UUFDcEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsSUFBSSxHQUFHLENBQUM7UUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUM7UUFFdEMsT0FBTyxPQUFPLEtBQUssUUFBUTtZQUN6QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLElBQUksVUFBVSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFO1lBQzdELENBQUMsQ0FBQyxHQUFHLE9BQU8sTUFBTSxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksSUFBSSxRQUFRLEVBQUUsQ0FBQztJQUM3RCxDQUFDO0lBRUQsb0ZBQW9GO0lBQ3BGLElBQUksYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDbEcsQ0FBQztJQUVELElBQUksT0FBTztRQUNULElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDO1FBQ2hGLElB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
@@ -1,17 +1,17 @@
1
- import { ConnectionOptionsObj } from '../types';
2
- export type SourceError = 'Proxy' | 'Database';
3
- declare class BaseError extends Error {
4
- source: SourceError;
5
- uri: string;
1
+ export type ErrorSource = 'Proxy' | 'Database';
2
+ declare abstract class BaseError extends Error {
3
+ abstract readonly source: ErrorSource;
4
+ readonly uri: string;
6
5
  readonly details: string;
7
- constructor(message: string, details?: string);
6
+ constructor(message: string, uri: string, details?: string);
8
7
  }
9
8
  export declare class DatabaseConnectError extends BaseError {
10
- constructor(message: string, databaseUri?: string, source?: SourceError);
9
+ readonly source: ErrorSource;
10
+ constructor(message: string, debugDatabaseUri: string, source?: ErrorSource);
11
11
  }
12
12
  export declare class ProxyConnectError extends BaseError {
13
- constructor(message: string, proxyConfig?: ConnectionOptionsObj['proxySocks']);
14
- private static buildSanitizedUriFromConfig;
13
+ readonly source = "Proxy";
14
+ constructor(message: string, debugProxyUri: string);
15
15
  }
16
16
  export {};
17
17
  //# sourceMappingURL=errors.d.ts.map
@@ -1,59 +1,29 @@
1
1
  "use strict";
2
+ /* eslint-disable max-classes-per-file */
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.ProxyConnectError = exports.DatabaseConnectError = void 0;
4
- function sanitizeUri(uri) {
5
- const uriObject = new URL(uri);
6
- if (uriObject.password) {
7
- uriObject.password = '**sanitizedPassword**';
8
- }
9
- return uriObject.toString();
10
- }
11
5
  class BaseError extends Error {
12
- constructor(message, details) {
13
- const messageWithDetails = details ? `${message}\n${details}` : message;
14
- super(messageWithDetails);
6
+ constructor(message, uri, details) {
7
+ super(details ? `${message}\n${details}` : message);
8
+ this.name = this.constructor.name;
15
9
  this.details = details;
10
+ this.uri = uri;
16
11
  }
17
12
  }
18
13
  class DatabaseConnectError extends BaseError {
19
- constructor(message, databaseUri, source = 'Database') {
20
- if (databaseUri) {
21
- const sanitizedUri = sanitizeUri(databaseUri);
22
- super(`Unable to connect to the given uri: ${sanitizedUri}.`, message);
23
- this.uri = sanitizedUri;
24
- }
25
- else {
26
- super(`Unable to connect to the given uri.`, message);
27
- }
28
- this.name = this.constructor.name;
14
+ constructor(message, debugDatabaseUri, source = 'Database') {
15
+ super(`Unable to connect to the given uri: ${debugDatabaseUri}.`, debugDatabaseUri, message);
29
16
  this.source = source;
30
17
  }
31
18
  }
32
19
  exports.DatabaseConnectError = DatabaseConnectError;
33
20
  class ProxyConnectError extends BaseError {
34
- constructor(message, proxyConfig) {
35
- const defaultMessage = 'Your proxy has encountered an error.';
36
- if (proxyConfig) {
37
- const sanitizedUri = ProxyConnectError.buildSanitizedUriFromConfig(proxyConfig);
38
- super(`${defaultMessage} Unable to connect to the given uri: ${sanitizedUri}.`, message);
39
- this.uri = sanitizedUri;
40
- }
41
- else {
42
- super(defaultMessage, message);
43
- }
44
- this.name = this.constructor.name;
21
+ constructor(message, debugProxyUri) {
22
+ // remove tcp protocol because its not added by the user
23
+ const sanitizedUri = debugProxyUri.replace('tcp://', '');
24
+ super(`Your proxy has encountered an error. Unable to connect to the given uri: ${sanitizedUri}.`, sanitizedUri, message);
45
25
  this.source = 'Proxy';
46
26
  }
47
- static buildSanitizedUriFromConfig(proxyConfig) {
48
- const proxyUri = new URL(`socks://${proxyConfig.host}:${proxyConfig.port}`);
49
- if (proxyConfig.userId) {
50
- proxyUri.username = proxyConfig.userId;
51
- }
52
- if (proxyConfig.password) {
53
- proxyUri.password = proxyConfig.password;
54
- }
55
- return sanitizeUri(proxyUri.toString()).replace('socks://', '');
56
- }
57
27
  }
58
28
  exports.ProxyConnectError = ProxyConnectError;
59
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nvbm5lY3Rpb24vZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUdBLFNBQVMsV0FBVyxDQUFDLEdBQVc7SUFDOUIsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFL0IsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ3RCLFNBQVMsQ0FBQyxRQUFRLEdBQUcsdUJBQXVCLENBQUM7S0FDOUM7SUFFRCxPQUFPLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUM5QixDQUFDO0FBSUQsTUFBTSxTQUFVLFNBQVEsS0FBSztJQUszQixZQUFZLE9BQWUsRUFBRSxPQUFnQjtRQUMzQyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLEtBQUssT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4RSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUUxQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN6QixDQUFDO0NBQ0Y7QUFFRCxNQUFhLG9CQUFxQixTQUFRLFNBQVM7SUFDakQsWUFBWSxPQUFlLEVBQUUsV0FBb0IsRUFBRSxTQUFzQixVQUFVO1FBQ2pGLElBQUksV0FBVyxFQUFFO1lBQ2YsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzlDLEtBQUssQ0FBQyx1Q0FBdUMsWUFBWSxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkUsSUFBSSxDQUFDLEdBQUcsR0FBRyxZQUFZLENBQUM7U0FDekI7YUFBTTtZQUNMLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUN2RDtRQUVELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBYkQsb0RBYUM7QUFFRCxNQUFhLGlCQUFrQixTQUFRLFNBQVM7SUFDOUMsWUFBWSxPQUFlLEVBQUUsV0FBZ0Q7UUFDM0UsTUFBTSxjQUFjLEdBQUcsc0NBQXNDLENBQUM7UUFFOUQsSUFBSSxXQUFXLEVBQUU7WUFDZixNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQywyQkFBMkIsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNoRixLQUFLLENBQUMsR0FBRyxjQUFjLHdDQUF3QyxZQUFZLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN6RixJQUFJLENBQUMsR0FBRyxHQUFHLFlBQVksQ0FBQztTQUN6QjthQUFNO1lBQ0wsS0FBSyxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNoQztRQUVELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVPLE1BQU0sQ0FBQywyQkFBMkIsQ0FDeEMsV0FBK0M7UUFFL0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxXQUFXLENBQUMsSUFBSSxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRTtZQUN0QixRQUFRLENBQUMsUUFBUSxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUM7U0FDeEM7UUFFRCxJQUFJLFdBQVcsQ0FBQyxRQUFRLEVBQUU7WUFDeEIsUUFBUSxDQUFDLFFBQVEsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDO1NBQzFDO1FBRUQsT0FBTyxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNsRSxDQUFDO0NBQ0Y7QUEvQkQsOENBK0JDIn0=
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nvbm5lY3Rpb24vZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx5Q0FBeUM7OztBQUl6QyxNQUFlLFNBQVUsU0FBUSxLQUFLO0lBS3BDLFlBQVksT0FBZSxFQUFFLEdBQVcsRUFBRSxPQUFnQjtRQUN4RCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sS0FBSyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0NBQ0Y7QUFFRCxNQUFhLG9CQUFxQixTQUFRLFNBQVM7SUFHakQsWUFBWSxPQUFlLEVBQUUsZ0JBQXdCLEVBQUUsU0FBc0IsVUFBVTtRQUNyRixLQUFLLENBQUMsdUNBQXVDLGdCQUFnQixHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFN0YsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBUkQsb0RBUUM7QUFFRCxNQUFhLGlCQUFrQixTQUFRLFNBQVM7SUFHOUMsWUFBWSxPQUFlLEVBQUUsYUFBcUI7UUFDaEQsd0RBQXdEO1FBQ3hELE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXpELEtBQUssQ0FDSCw0RUFBNEUsWUFBWSxHQUFHLEVBQzNGLFlBQVksRUFDWixPQUFPLENBQ1IsQ0FBQztRQVZLLFdBQU0sR0FBRyxPQUFPLENBQUM7SUFXMUIsQ0FBQztDQUNGO0FBYkQsOENBYUMifQ==
@@ -1,4 +1,3 @@
1
- import ReverseProxy from './reverse-proxy';
2
- import { ConnectionOptionsObj } from '../types';
3
- export default function handleErrors(error: Error, options?: ConnectionOptionsObj, proxy?: ReverseProxy): void;
1
+ import ConnectionOptions from './connection-options';
2
+ export default function handleErrors(error: Error, options: ConnectionOptions): void;
4
3
  //# sourceMappingURL=handle-errors.d.ts.map
@@ -2,25 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const sequelize_1 = require("sequelize");
4
4
  const errors_1 = require("./errors");
5
- function handleProxyErrors(error, databaseUri, proxyConfig) {
6
- // eslint-disable-next-line max-len
7
- // @link: list of errors thrown by the proxy https://github.com/JoshGlazebrook/socks/blob/76d013e4c9a2d956f07868477d8f12ec0b96edfc/src/common/constants.ts#LL10C10-L10C10
8
- if (error?.stack.includes('SocksClient')) {
9
- if (error.message.includes('Socket closed') ||
10
- error.message.includes('Socks5 proxy rejected connection')) {
11
- throw new errors_1.DatabaseConnectError(null, databaseUri, 'Proxy');
12
- }
13
- throw new errors_1.ProxyConnectError(error.message, proxyConfig);
5
+ function handleProxyErrors(error, options) {
6
+ /** @see https://github.com/JoshGlazebrook/socks/blob/76d013/src/common/constants.ts#L10 */
7
+ if (error.message.includes('Socket closed') ||
8
+ error.message.includes('Socks5 proxy rejected connection')) {
9
+ throw new errors_1.DatabaseConnectError(null, options.debugDatabaseUri, 'Proxy');
14
10
  }
11
+ throw new errors_1.ProxyConnectError(error.message, options.debugProxyUri);
15
12
  }
16
- function handleErrors(error, options, proxy) {
17
- handleProxyErrors(error, proxy?.destination.uri, proxy?.destination.proxySocks);
13
+ function handleSequelizeError(error, options) {
14
+ const nameWithoutSequelize = error.name.replace('Sequelize', '');
15
+ const nameWithSpaces = nameWithoutSequelize.replace(/([a-z])([A-Z])/g, (_, m1, m2) => `${m1} ${m2.toLowerCase()}`);
16
+ throw new errors_1.DatabaseConnectError(`${nameWithSpaces}: ${error.message}`, options.debugDatabaseUri);
17
+ }
18
+ function handleErrors(error, options) {
19
+ if (error?.stack?.includes('SocksClient')) {
20
+ handleProxyErrors(error, options);
21
+ }
18
22
  if (error instanceof sequelize_1.BaseError) {
19
- const nameWithoutSequelize = error.name.replace('Sequelize', '');
20
- const nameWithSpaces = nameWithoutSequelize.replace(/([a-z])([A-Z])/g, (_, m1, m2) => `${m1} ${m2.toLowerCase()}`);
21
- throw new errors_1.DatabaseConnectError(`${nameWithSpaces}: ${error.message}`, options?.uri);
23
+ handleSequelizeError(error, options);
22
24
  }
23
25
  throw error;
24
26
  }
25
27
  exports.default = handleErrors;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlLWVycm9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25uZWN0aW9uL2hhbmRsZS1lcnJvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBc0M7QUFFdEMscUNBQW1FO0FBSW5FLFNBQVMsaUJBQWlCLENBQ3hCLEtBQVksRUFDWixXQUFvQixFQUNwQixXQUFnRDtJQUVoRCxtQ0FBbUM7SUFDbkMseUtBQXlLO0lBQ3pLLElBQUksS0FBSyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7UUFDeEMsSUFDRSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7WUFDdkMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsa0NBQWtDLENBQUMsRUFDMUQ7WUFDQSxNQUFNLElBQUksNkJBQW9CLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUM1RDtRQUVELE1BQU0sSUFBSSwwQkFBaUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0tBQ3pEO0FBQ0gsQ0FBQztBQUVELFNBQXdCLFlBQVksQ0FDbEMsS0FBWSxFQUNaLE9BQThCLEVBQzlCLEtBQW9CO0lBRXBCLGlCQUFpQixDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRWhGLElBQUksS0FBSyxZQUFZLHFCQUFTLEVBQUU7UUFDOUIsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakUsTUFBTSxjQUFjLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxDQUNqRCxpQkFBaUIsRUFDakIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQzNDLENBQUM7UUFFRixNQUFNLElBQUksNkJBQW9CLENBQUMsR0FBRyxjQUFjLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztLQUNyRjtJQUVELE1BQU0sS0FBSyxDQUFDO0FBQ2QsQ0FBQztBQWxCRCwrQkFrQkMifQ==
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlLWVycm9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25uZWN0aW9uL2hhbmRsZS1lcnJvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBd0Q7QUFHeEQscUNBQW1FO0FBRW5FLFNBQVMsaUJBQWlCLENBQUMsS0FBWSxFQUFFLE9BQTBCO0lBQ2pFLDJGQUEyRjtJQUMzRixJQUNFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUN2QyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxrQ0FBa0MsQ0FBQyxFQUMxRDtRQUNBLE1BQU0sSUFBSSw2QkFBb0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQ3pFO0lBRUQsTUFBTSxJQUFJLDBCQUFpQixDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUFDLEtBQXFCLEVBQUUsT0FBMEI7SUFDN0UsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakUsTUFBTSxjQUFjLEdBQUcsb0JBQW9CLENBQUMsT0FBTyxDQUNqRCxpQkFBaUIsRUFDakIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQzNDLENBQUM7SUFFRixNQUFNLElBQUksNkJBQW9CLENBQUMsR0FBRyxjQUFjLEtBQUssS0FBSyxDQUFDLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ2xHLENBQUM7QUFFRCxTQUF3QixZQUFZLENBQUMsS0FBWSxFQUFFLE9BQTBCO0lBQzNFLElBQUksS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7UUFDekMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQ25DO0lBRUQsSUFBSSxLQUFLLFlBQVkscUJBQWMsRUFBRTtRQUNuQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDdEM7SUFFRCxNQUFNLEtBQUssQ0FBQztBQUNkLENBQUM7QUFWRCwrQkFVQyJ9
@@ -1,6 +1,5 @@
1
- import type { ConnectionOptions } from '../types';
2
- import type { Logger } from '@forestadmin/datasource-toolkit';
3
1
  import { Sequelize } from 'sequelize';
2
+ import ConnectionOptions from './connection-options';
4
3
  /** Attempt to connect to the database */
5
- export default function connect(uriOrOptions: ConnectionOptions, logger?: Logger): Promise<Sequelize>;
4
+ export default function connect(options: ConnectionOptions): Promise<Sequelize>;
6
5
  //# sourceMappingURL=index.d.ts.map
@@ -3,57 +3,37 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const sequelize_1 = require("sequelize");
7
6
  const handle_errors_1 = __importDefault(require("./handle-errors"));
8
- const preprocess_1 = __importDefault(require("./preprocess"));
9
- const reverse_proxy_1 = __importDefault(require("./reverse-proxy"));
10
- const utils_1 = require("./utils");
7
+ const reverse_proxy_1 = __importDefault(require("./services/reverse-proxy"));
8
+ const sequelize_factory_1 = __importDefault(require("./services/sequelize-factory"));
9
+ const tcp_server_1 = __importDefault(require("./services/tcp-server"));
11
10
  /** Attempt to connect to the database */
12
- async function connect(uriOrOptions, logger) {
11
+ async function connect(options) {
13
12
  let proxy;
13
+ let tcpServer;
14
14
  let sequelize;
15
- let options;
16
- let servername;
17
15
  try {
18
- options = await (0, preprocess_1.default)(uriOrOptions);
19
- try {
20
- servername = options?.host ?? new URL(options.uri).hostname;
16
+ if (options.proxyOptions) {
17
+ tcpServer = new tcp_server_1.default();
18
+ await tcpServer.start();
19
+ proxy = new reverse_proxy_1.default(options.proxyOptions, options.host, options.port);
20
+ tcpServer.onConnect(proxy.connectListener.bind(proxy));
21
+ tcpServer.onClose(proxy.closeListener.bind(proxy));
22
+ // swap database host and port with the ones from the proxy.
23
+ options.changeHostAndPort(tcpServer.host, tcpServer.port);
21
24
  }
22
- catch {
23
- // don't crash if using unix socket, sqlite, etc...
24
- }
25
- if (options.proxySocks) {
26
- proxy = new reverse_proxy_1.default(options);
27
- await proxy.start();
28
- options = proxy.connectionOptions;
29
- }
30
- const { uri, sslMode, ...opts } = options;
31
- const schema = opts.schema ?? (0, utils_1.getSchema)(uri);
32
- const logging = logger ? (0, utils_1.getLogger)(logger) : false;
33
- opts.dialectOptions = {
34
- ...(opts.dialectOptions ?? {}),
35
- ...(0, utils_1.getSslConfiguration)(opts.dialect, sslMode, servername, logger),
36
- };
37
- sequelize = uri
38
- ? new sequelize_1.Sequelize(uri, { ...opts, schema, logging })
39
- : new sequelize_1.Sequelize({ ...opts, schema, logging });
40
- // we want to stop the proxy when the sequelize connection is closed
41
- sequelize.close = async function close() {
42
- try {
43
- await sequelize_1.Sequelize.prototype.close.call(this);
44
- }
45
- finally {
46
- await proxy?.stop();
47
- }
48
- };
25
+ const sequelizeFactory = new sequelize_factory_1.default();
26
+ if (tcpServer)
27
+ sequelizeFactory.onClose(tcpServer.closeListener.bind(tcpServer));
28
+ sequelize = sequelizeFactory.build(await options.buildSequelizeCtorOptions());
49
29
  await sequelize.authenticate(); // Test connection
50
30
  return sequelize;
51
31
  }
52
32
  catch (e) {
53
33
  await sequelize?.close();
54
34
  // if proxy encountered an error, we want to throw it instead of the sequelize error
55
- (0, handle_errors_1.default)(proxy?.error || e, options, proxy);
35
+ (0, handle_errors_1.default)(proxy?.error ?? e, options);
56
36
  }
57
37
  }
58
38
  exports.default = connect;
59
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29ubmVjdGlvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUdBLHlDQUFzQztBQUV0QyxvRUFBMkM7QUFDM0MsOERBQTZDO0FBQzdDLG9FQUEyQztBQUMzQyxtQ0FBb0U7QUFFcEUseUNBQXlDO0FBQzFCLEtBQUssVUFBVSxPQUFPLENBQ25DLFlBQStCLEVBQy9CLE1BQWU7SUFFZixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxTQUFvQixDQUFDO0lBQ3pCLElBQUksT0FBNkIsQ0FBQztJQUNsQyxJQUFJLFVBQWtCLENBQUM7SUFFdkIsSUFBSTtRQUNGLE9BQU8sR0FBRyxNQUFNLElBQUEsb0JBQWlCLEVBQUMsWUFBWSxDQUFDLENBQUM7UUFFaEQsSUFBSTtZQUNGLFVBQVUsR0FBRyxPQUFPLEVBQUUsSUFBSSxJQUFJLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUM7U0FDN0Q7UUFBQyxNQUFNO1lBQ04sbURBQW1EO1NBQ3BEO1FBRUQsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFO1lBQ3RCLEtBQUssR0FBRyxJQUFJLHVCQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEMsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDcEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztTQUNuQztRQUVELE1BQU0sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBQzFDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksSUFBQSxpQkFBUyxFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBQSxpQkFBUyxFQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFFbkQsSUFBSSxDQUFDLGNBQWMsR0FBRztZQUNwQixHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxFQUFFLENBQUM7WUFDOUIsR0FBRyxJQUFBLDJCQUFtQixFQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUM7U0FDbEUsQ0FBQztRQUVGLFNBQVMsR0FBRyxHQUFHO1lBQ2IsQ0FBQyxDQUFDLElBQUkscUJBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDbEQsQ0FBQyxDQUFDLElBQUkscUJBQVMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBRWhELG9FQUFvRTtRQUNwRSxTQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssVUFBVSxLQUFLO1lBQ3BDLElBQUk7Z0JBQ0YsTUFBTSxxQkFBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzVDO29CQUFTO2dCQUNSLE1BQU0sS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO2FBQ3JCO1FBQ0gsQ0FBQyxDQUFDO1FBRUYsTUFBTSxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxrQkFBa0I7UUFFbEQsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE1BQU0sU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ3pCLG9GQUFvRjtRQUNwRixJQUFBLHVCQUFZLEVBQUMsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0tBQ2pEO0FBQ0gsQ0FBQztBQXRERCwwQkFzREMifQ==
39
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29ubmVjdGlvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUdBLG9FQUEyQztBQUMzQyw2RUFBb0Q7QUFDcEQscUZBQTREO0FBQzVELHVFQUE4QztBQUU5Qyx5Q0FBeUM7QUFDMUIsS0FBSyxVQUFVLE9BQU8sQ0FBQyxPQUEwQjtJQUM5RCxJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxTQUFvQixDQUFDO0lBQ3pCLElBQUksU0FBb0IsQ0FBQztJQUV6QixJQUFJO1FBQ0YsSUFBSSxPQUFPLENBQUMsWUFBWSxFQUFFO1lBQ3hCLFNBQVMsR0FBRyxJQUFJLG9CQUFTLEVBQUUsQ0FBQztZQUM1QixNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4QixLQUFLLEdBQUcsSUFBSSx1QkFBWSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0UsU0FBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNuRCw0REFBNEQ7WUFDNUQsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzNEO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLDJCQUFnQixFQUFFLENBQUM7UUFDaEQsSUFBSSxTQUFTO1lBQUUsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFFakYsU0FBUyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxNQUFNLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUM7UUFDOUUsTUFBTSxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxrQkFBa0I7UUFFbEQsT0FBTyxTQUFTLENBQUM7S0FDbEI7SUFBQyxPQUFPLENBQUMsRUFBRTtRQUNWLE1BQU0sU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ3pCLG9GQUFvRjtRQUNwRixJQUFBLHVCQUFZLEVBQUMsS0FBSyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7S0FDMUM7QUFDSCxDQUFDO0FBNUJELDBCQTRCQyJ9
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" />
2
+ import net from 'net';
3
+ import Service from './service';
4
+ import { ProxyOptions } from '../../types';
5
+ export default class ReverseProxy extends Service {
6
+ private readonly errors;
7
+ private readonly connectedClients;
8
+ private readonly options;
9
+ private readonly targetHost;
10
+ private readonly targetPort;
11
+ get error(): Error | null;
12
+ constructor(proxyOptions: ProxyOptions, targetHost: string, targetPort: number);
13
+ closeListener(): Promise<void>;
14
+ connectListener(socket: net.Socket): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=reverse-proxy.d.ts.map
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const socks_1 = require("socks");
7
+ const service_1 = __importDefault(require("./service"));
8
+ class ReverseProxy extends service_1.default {
9
+ get error() {
10
+ return this.errors.length > 0 ? this.errors[0] : null;
11
+ }
12
+ constructor(proxyOptions, targetHost, targetPort) {
13
+ super();
14
+ this.errors = [];
15
+ this.connectedClients = new Set();
16
+ this.options = proxyOptions;
17
+ this.targetHost = targetHost;
18
+ this.targetPort = targetPort;
19
+ if (!this.targetHost)
20
+ throw new Error('Host is required');
21
+ if (!this.targetPort)
22
+ throw new Error('Port is required');
23
+ }
24
+ async closeListener() {
25
+ await super.closeListener();
26
+ this.connectedClients.forEach(client => client.destroy());
27
+ }
28
+ async connectListener(socket) {
29
+ let socks5Proxy;
30
+ this.connectedClients.add(socket);
31
+ socket.on('error', error => {
32
+ this.errors.push(error);
33
+ if (!socket.closed)
34
+ socket.destroy(error);
35
+ });
36
+ socket.on('close', () => {
37
+ this.connectedClients.delete(socket);
38
+ if (!socks5Proxy?.socket.closed)
39
+ socks5Proxy?.socket.destroy();
40
+ });
41
+ try {
42
+ socks5Proxy = await socks_1.SocksClient.createConnection({
43
+ proxy: { ...this.options, type: 5 },
44
+ command: 'connect',
45
+ destination: { host: this.targetHost, port: this.targetPort },
46
+ timeout: 4000,
47
+ });
48
+ socks5Proxy.socket.on('close', () => {
49
+ this.connectedClients.delete(socks5Proxy.socket);
50
+ if (!socket.closed)
51
+ socket.destroy();
52
+ });
53
+ socks5Proxy.socket.on('error', socket.destroy);
54
+ socks5Proxy.socket.pipe(socket).pipe(socks5Proxy.socket);
55
+ await super.connectListener(socks5Proxy.socket);
56
+ }
57
+ catch (err) {
58
+ socket.destroy(err);
59
+ }
60
+ }
61
+ }
62
+ exports.default = ReverseProxy;
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV2ZXJzZS1wcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb25uZWN0aW9uL3NlcnZpY2VzL3JldmVyc2UtcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFDQSxpQ0FBb0M7QUFHcEMsd0RBQWdDO0FBR2hDLE1BQXFCLFlBQWEsU0FBUSxpQkFBTztJQU8vQyxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3hELENBQUM7SUFFRCxZQUFZLFlBQTBCLEVBQUUsVUFBa0IsRUFBRSxVQUFrQjtRQUM1RSxLQUFLLEVBQUUsQ0FBQztRQVhPLFdBQU0sR0FBWSxFQUFFLENBQUM7UUFDckIscUJBQWdCLEdBQW9CLElBQUksR0FBRyxFQUFFLENBQUM7UUFXN0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxZQUFZLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRVEsS0FBSyxDQUFDLGFBQWE7UUFDMUIsTUFBTSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFUSxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQWtCO1FBQy9DLElBQUksV0FBd0MsQ0FBQztRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWxDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtnQkFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ3RCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsSUFBSSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsTUFBTTtnQkFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSTtZQUNGLFdBQVcsR0FBRyxNQUFNLG1CQUFXLENBQUMsZ0JBQWdCLENBQUM7Z0JBQy9DLEtBQUssRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO2dCQUNuQyxPQUFPLEVBQUUsU0FBUztnQkFDbEIsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQzdELE9BQU8sRUFBRSxJQUFJO2FBQ2QsQ0FBQyxDQUFDO1lBRUgsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtvQkFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdkMsQ0FBQyxDQUFDLENBQUM7WUFDSCxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQy9DLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFekQsTUFBTSxLQUFLLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUNqRDtRQUFDLE9BQU8sR0FBRyxFQUFFO1lBQ1osTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFZLENBQUMsQ0FBQztTQUM5QjtJQUNILENBQUM7Q0FDRjtBQTFERCwrQkEwREMifQ==
@@ -0,0 +1,8 @@
1
+ import { Sequelize } from 'sequelize';
2
+ import { Options as SequelizeOptions } from 'sequelize/types/sequelize';
3
+ import Service from './service';
4
+ export default class SequelizeFactory extends Service {
5
+ build(sequelizeCtorOptions: [SequelizeOptions] | [string, SequelizeOptions]): Sequelize;
6
+ private overrideCloseMethod;
7
+ }
8
+ //# sourceMappingURL=sequelize-factory.d.ts.map
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const sequelize_1 = require("sequelize");
7
+ const service_1 = __importDefault(require("./service"));
8
+ class SequelizeFactory extends service_1.default {
9
+ build(sequelizeCtorOptions) {
10
+ const sequelize = sequelizeCtorOptions.length === 1
11
+ ? new sequelize_1.Sequelize(sequelizeCtorOptions[0])
12
+ : new sequelize_1.Sequelize(sequelizeCtorOptions[0], sequelizeCtorOptions[1]);
13
+ this.overrideCloseMethod(sequelize);
14
+ return sequelize;
15
+ }
16
+ overrideCloseMethod(sequelize) {
17
+ const closeListener = this.closeListener.bind(this);
18
+ // override close method to ensure to execute the closeListener
19
+ sequelize.close = async function close() {
20
+ try {
21
+ await sequelize_1.Sequelize.prototype.close.call(this);
22
+ }
23
+ finally {
24
+ await closeListener();
25
+ }
26
+ };
27
+ }
28
+ }
29
+ exports.default = SequelizeFactory;
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVsaXplLWZhY3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29ubmVjdGlvbi9zZXJ2aWNlcy9zZXF1ZWxpemUtZmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlDQUFzQztBQUd0Qyx3REFBZ0M7QUFFaEMsTUFBcUIsZ0JBQWlCLFNBQVEsaUJBQU87SUFDbkQsS0FBSyxDQUFDLG9CQUFxRTtRQUN6RSxNQUFNLFNBQVMsR0FDYixvQkFBb0IsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUMvQixDQUFDLENBQUMsSUFBSSxxQkFBUyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxJQUFJLHFCQUFTLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0RSxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEMsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVPLG1CQUFtQixDQUFDLFNBQW9CO1FBQzlDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBELCtEQUErRDtRQUMvRCxTQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssVUFBVSxLQUFLO1lBQ3BDLElBQUk7Z0JBQ0YsTUFBTSxxQkFBUyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzVDO29CQUFTO2dCQUNSLE1BQU0sYUFBYSxFQUFFLENBQUM7YUFDdkI7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF4QkQsbUNBd0JDIn0=
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" />
2
+ import net from 'net';
3
+ export type ConnectionCallback = (socket: net.Socket) => Promise<void>;
4
+ export type CloseCallback = () => Promise<void>;
5
+ export default abstract class Service {
6
+ private connectionCallback;
7
+ private closeCallback;
8
+ /** attach a callback when there is a new connection on the service. */
9
+ onConnect(callback: ConnectionCallback): void;
10
+ /** callback to execute when there is a new connection. */
11
+ connectListener(socket: net.Socket): Promise<void>;
12
+ /** attach a callback when a service is closing. */
13
+ onClose(callback: CloseCallback): void;
14
+ /** callback to execute when the service is closing. */
15
+ closeListener(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Service {
4
+ /** attach a callback when there is a new connection on the service. */
5
+ onConnect(callback) {
6
+ this.connectionCallback = callback;
7
+ }
8
+ /** callback to execute when there is a new connection. */
9
+ async connectListener(socket) {
10
+ await this.connectionCallback?.(socket);
11
+ }
12
+ /** attach a callback when a service is closing. */
13
+ onClose(callback) {
14
+ this.closeCallback = callback;
15
+ }
16
+ /** callback to execute when the service is closing. */
17
+ async closeListener() {
18
+ await this.closeCallback?.();
19
+ }
20
+ }
21
+ exports.default = Service;
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb25uZWN0aW9uL3NlcnZpY2VzL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFLQSxNQUE4QixPQUFPO0lBSW5DLHVFQUF1RTtJQUN2RSxTQUFTLENBQUMsUUFBNEI7UUFDcEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztJQUNyQyxDQUFDO0lBRUQsMERBQTBEO0lBQzFELEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBa0I7UUFDdEMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsbURBQW1EO0lBQ25ELE9BQU8sQ0FBQyxRQUF1QjtRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQztJQUNoQyxDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELEtBQUssQ0FBQyxhQUFhO1FBQ2pCLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUM7SUFDL0IsQ0FBQztDQUNGO0FBdkJELDBCQXVCQyJ9
@@ -0,0 +1,12 @@
1
+ import Service from './service';
2
+ /** TcpServer is used as proxy to redirect all the database requests */
3
+ export default class TcpServer extends Service {
4
+ private readonly server;
5
+ get host(): string;
6
+ get port(): number;
7
+ constructor();
8
+ start(): Promise<void>;
9
+ stop(): Promise<void>;
10
+ closeListener(): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=tcp-server.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const net_1 = __importDefault(require("net"));
7
+ const service_1 = __importDefault(require("./service"));
8
+ /** TcpServer is used as proxy to redirect all the database requests */
9
+ class TcpServer extends service_1.default {
10
+ get host() {
11
+ return this.server.address().address;
12
+ }
13
+ get port() {
14
+ return this.server.address().port;
15
+ }
16
+ constructor() {
17
+ super();
18
+ this.server = net_1.default.createServer(this.connectListener.bind(this));
19
+ }
20
+ start() {
21
+ return new Promise((resolve, reject) => {
22
+ this.server.on('error', reject);
23
+ // By using port 0, the operating system
24
+ // will assign an available port for the server to listen on.
25
+ this.server.listen(0, '127.0.0.1', resolve);
26
+ });
27
+ }
28
+ async stop() {
29
+ try {
30
+ await super.closeListener();
31
+ }
32
+ finally {
33
+ await new Promise((resolve, reject) => {
34
+ this.server.close(e => {
35
+ if (e)
36
+ reject(e);
37
+ else
38
+ resolve();
39
+ });
40
+ });
41
+ }
42
+ }
43
+ async closeListener() {
44
+ await this.stop();
45
+ }
46
+ }
47
+ exports.default = TcpServer;
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGNwLXNlcnZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb25uZWN0aW9uL3NlcnZpY2VzL3RjcC1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4Q0FBc0I7QUFFdEIsd0RBQWdDO0FBRWhDLHVFQUF1RTtBQUN2RSxNQUFxQixTQUFVLFNBQVEsaUJBQU87SUFHNUMsSUFBSSxJQUFJO1FBQ04sT0FBUSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBc0IsQ0FBQyxPQUFPLENBQUM7SUFDNUQsQ0FBQztJQUVELElBQUksSUFBSTtRQUNOLE9BQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQXNCLENBQUMsSUFBSSxDQUFDO0lBQ3pELENBQUM7SUFFRDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE1BQU0sR0FBRyxhQUFHLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELEtBQUs7UUFDSCxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNoQyx3Q0FBd0M7WUFDeEMsNkRBQTZEO1lBQzdELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJO1lBQ0YsTUFBTSxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDN0I7Z0JBQVM7WUFDUixNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUMxQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDcEIsSUFBSSxDQUFDO3dCQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzs7d0JBQ1osT0FBTyxFQUFFLENBQUM7Z0JBQ2pCLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFUSxLQUFLLENBQUMsYUFBYTtRQUMxQixNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNwQixDQUFDO0NBQ0Y7QUF6Q0QsNEJBeUNDIn0=
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import type { Table } from './introspection/types';
2
- import type { ConnectionOptions, SslMode } from './types';
2
+ import type { PlainConnectionOptions, PlainConnectionOptionsOrUri } from './types';
3
3
  import type { DataSourceFactory, Logger } from '@forestadmin/datasource-toolkit';
4
4
  import { Sequelize } from 'sequelize';
5
- export declare function introspect(uriOrOptions: ConnectionOptions, logger?: Logger): Promise<Table[]>;
6
- export declare function buildSequelizeInstance(uriOrOptions: ConnectionOptions, logger: Logger, introspection?: Table[]): Promise<Sequelize>;
7
- export declare function createSqlDataSource(uriOrOptions: ConnectionOptions, options?: {
5
+ export declare function introspect(uriOrOptions: PlainConnectionOptionsOrUri, logger?: Logger): Promise<Table[]>;
6
+ export declare function buildSequelizeInstance(uriOrOptions: PlainConnectionOptionsOrUri, logger: Logger, introspection?: Table[]): Promise<Sequelize>;
7
+ export declare function createSqlDataSource(uriOrOptions: PlainConnectionOptionsOrUri, options?: {
8
8
  introspection: Table[];
9
9
  }): DataSourceFactory;
10
- export type { ConnectionOptions, Table, SslMode };
11
- export { default as preprocessOptions } from './connection/preprocess';
10
+ /** Preprocess the connection options so that they can be cached for faster connections */
11
+ export declare function preprocessOptions(uriOrOptions: PlainConnectionOptionsOrUri): Promise<PlainConnectionOptions>;
12
12
  export * from './connection/errors';
13
13
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -20,13 +20,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.preprocessOptions = exports.createSqlDataSource = exports.buildSequelizeInstance = exports.introspect = void 0;
21
21
  const datasource_sequelize_1 = require("@forestadmin/datasource-sequelize");
22
22
  const connection_1 = __importDefault(require("./connection"));
23
+ const connection_options_1 = __importDefault(require("./connection/connection-options"));
23
24
  const introspector_1 = __importDefault(require("./introspection/introspector"));
24
25
  const model_1 = __importDefault(require("./orm-builder/model"));
25
26
  const relations_1 = __importDefault(require("./orm-builder/relations"));
26
27
  async function introspect(uriOrOptions, logger) {
28
+ const options = new connection_options_1.default(uriOrOptions, logger);
27
29
  let sequelize;
28
30
  try {
29
- sequelize = await (0, connection_1.default)(uriOrOptions, logger);
31
+ sequelize = await (0, connection_1.default)(options);
30
32
  return await introspector_1.default.introspect(sequelize, logger);
31
33
  }
32
34
  finally {
@@ -35,9 +37,10 @@ async function introspect(uriOrOptions, logger) {
35
37
  }
36
38
  exports.introspect = introspect;
37
39
  async function buildSequelizeInstance(uriOrOptions, logger, introspection) {
40
+ const options = new connection_options_1.default(uriOrOptions, logger);
38
41
  let sequelize;
39
42
  try {
40
- sequelize = await (0, connection_1.default)(uriOrOptions, logger);
43
+ sequelize = await (0, connection_1.default)(options);
41
44
  const tables = introspection ?? (await introspector_1.default.introspect(sequelize, logger));
42
45
  model_1.default.defineModels(sequelize, logger, tables);
43
46
  relations_1.default.defineRelations(sequelize, logger, tables);
@@ -56,7 +59,10 @@ function createSqlDataSource(uriOrOptions, options) {
56
59
  };
57
60
  }
58
61
  exports.createSqlDataSource = createSqlDataSource;
59
- var preprocess_1 = require("./connection/preprocess");
60
- Object.defineProperty(exports, "preprocessOptions", { enumerable: true, get: function () { return __importDefault(preprocess_1).default; } });
62
+ /** Preprocess the connection options so that they can be cached for faster connections */
63
+ async function preprocessOptions(uriOrOptions) {
64
+ return new connection_options_1.default(uriOrOptions).buildPreprocessedOptions();
65
+ }
66
+ exports.preprocessOptions = preprocessOptions;
61
67
  __exportStar(require("./connection/errors"), exports);
62
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFJQSw0RUFBd0U7QUFHeEUsOERBQW1DO0FBQ25DLGdGQUF3RDtBQUN4RCxnRUFBK0M7QUFDL0Msd0VBQXNEO0FBRS9DLEtBQUssVUFBVSxVQUFVLENBQzlCLFlBQStCLEVBQy9CLE1BQWU7SUFFZixJQUFJLFNBQW9CLENBQUM7SUFFekIsSUFBSTtRQUNGLFNBQVMsR0FBRyxNQUFNLElBQUEsb0JBQU8sRUFBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFaEQsT0FBTyxNQUFNLHNCQUFZLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztLQUN6RDtZQUFTO1FBQ1IsTUFBTSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7S0FDMUI7QUFDSCxDQUFDO0FBYkQsZ0NBYUM7QUFFTSxLQUFLLFVBQVUsc0JBQXNCLENBQzFDLFlBQStCLEVBQy9CLE1BQWMsRUFDZCxhQUF1QjtJQUV2QixJQUFJLFNBQW9CLENBQUM7SUFFekIsSUFBSTtRQUNGLFNBQVMsR0FBRyxNQUFNLElBQUEsb0JBQU8sRUFBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEQsTUFBTSxNQUFNLEdBQUcsYUFBYSxJQUFJLENBQUMsTUFBTSxzQkFBWSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNuRixlQUFZLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDckQsbUJBQWUsQ0FBQyxlQUFlLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztLQUM1RDtJQUFDLE9BQU8sS0FBSyxFQUFFO1FBQ2QsTUFBTSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDekIsTUFBTSxLQUFLLENBQUM7S0FDYjtJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFsQkQsd0RBa0JDO0FBRUQsU0FBZ0IsbUJBQW1CLENBQ2pDLFlBQStCLEVBQy9CLE9BQW9DO0lBRXBDLE9BQU8sS0FBSyxFQUFFLE1BQWMsRUFBRSxFQUFFO1FBQzlCLE1BQU0sU0FBUyxHQUFHLE1BQU0sc0JBQXNCLENBQUMsWUFBWSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFFN0YsT0FBTyxJQUFJLDBDQUFtQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNwRCxDQUFDLENBQUM7QUFDSixDQUFDO0FBVEQsa0RBU0M7QUFHRCxzREFBdUU7QUFBOUQsZ0lBQUEsT0FBTyxPQUFxQjtBQUNyQyxzREFBb0MifQ==
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFJQSw0RUFBd0U7QUFHeEUsOERBQW1DO0FBQ25DLHlGQUFnRTtBQUNoRSxnRkFBd0Q7QUFDeEQsZ0VBQStDO0FBQy9DLHdFQUFzRDtBQUUvQyxLQUFLLFVBQVUsVUFBVSxDQUM5QixZQUF5QyxFQUN6QyxNQUFlO0lBRWYsTUFBTSxPQUFPLEdBQUcsSUFBSSw0QkFBaUIsQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUQsSUFBSSxTQUFvQixDQUFDO0lBRXpCLElBQUk7UUFDRixTQUFTLEdBQUcsTUFBTSxJQUFBLG9CQUFPLEVBQUMsT0FBTyxDQUFDLENBQUM7UUFFbkMsT0FBTyxNQUFNLHNCQUFZLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztLQUN6RDtZQUFTO1FBQ1IsTUFBTSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7S0FDMUI7QUFDSCxDQUFDO0FBZEQsZ0NBY0M7QUFFTSxLQUFLLFVBQVUsc0JBQXNCLENBQzFDLFlBQXlDLEVBQ3pDLE1BQWMsRUFDZCxhQUF1QjtJQUV2QixNQUFNLE9BQU8sR0FBRyxJQUFJLDRCQUFpQixDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM1RCxJQUFJLFNBQW9CLENBQUM7SUFFekIsSUFBSTtRQUNGLFNBQVMsR0FBRyxNQUFNLElBQUEsb0JBQU8sRUFBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxhQUFhLElBQUksQ0FBQyxNQUFNLHNCQUFZLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ25GLGVBQVksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyRCxtQkFBZSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0tBQzVEO0lBQUMsT0FBTyxLQUFLLEVBQUU7UUFDZCxNQUFNLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUN6QixNQUFNLEtBQUssQ0FBQztLQUNiO0lBRUQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQW5CRCx3REFtQkM7QUFFRCxTQUFnQixtQkFBbUIsQ0FDakMsWUFBeUMsRUFDekMsT0FBb0M7SUFFcEMsT0FBTyxLQUFLLEVBQUUsTUFBYyxFQUFFLEVBQUU7UUFDOUIsTUFBTSxTQUFTLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUU3RixPQUFPLElBQUksMENBQW1CLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3BELENBQUMsQ0FBQztBQUNKLENBQUM7QUFURCxrREFTQztBQUVELDBGQUEwRjtBQUNuRixLQUFLLFVBQVUsaUJBQWlCLENBQ3JDLFlBQXlDO0lBRXpDLE9BQU8sSUFBSSw0QkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0FBQ3hFLENBQUM7QUFKRCw4Q0FJQztBQUVELHNEQUFvQyJ9
package/dist/types.d.ts CHANGED
@@ -1,16 +1,19 @@
1
1
  import { Options } from 'sequelize/types';
2
- export type ConnectionOptionsObj = {
2
+ type SupportedSequelizeOptions = Pick<Options, 'database' | 'dialect' | 'dialectModule' | 'dialectModulePath' | 'dialectOptions' | 'host' | 'minifyAliases' | 'native' | 'password' | 'pool' | 'port' | 'protocol' | 'replication' | 'schema' | 'ssl' | 'storage' | 'username'>;
3
+ export type ProxyOptions = {
4
+ userId?: string;
5
+ password?: string;
6
+ host: string;
7
+ port: number;
8
+ version?: 5;
9
+ command?: 'connect';
10
+ };
11
+ export type PlainConnectionOptions = SupportedSequelizeOptions & {
3
12
  uri?: string;
4
13
  sslMode?: SslMode;
5
- proxySocks?: {
6
- userId?: string;
7
- password?: string;
8
- host: string;
9
- port: number;
10
- version?: 5;
11
- command?: 'connect';
12
- };
13
- } & Pick<Options, 'database' | 'dialect' | 'dialectModule' | 'dialectModulePath' | 'dialectOptions' | 'host' | 'minifyAliases' | 'native' | 'password' | 'pool' | 'port' | 'protocol' | 'replication' | 'schema' | 'ssl' | 'storage' | 'username'>;
14
- export type ConnectionOptions = ConnectionOptionsObj | string;
14
+ proxySocks?: ProxyOptions;
15
+ };
16
+ export type PlainConnectionOptionsOrUri = PlainConnectionOptions | string;
15
17
  export type SslMode = 'preferred' | 'disabled' | 'required' | 'verify' | 'manual';
18
+ export {};
16
19
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forestadmin/datasource-sql",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "main": "dist/index.js",
5
5
  "license": "GPL-3.0",
6
6
  "publishConfig": {
@@ -1,11 +0,0 @@
1
- import type { ConnectionOptions, ConnectionOptionsObj } from '../types';
2
- /**
3
- * Preprocess connection options.
4
- * Allows to speed up the connection process by avoiding attempts to connect to the database.
5
- *
6
- * It ensures that
7
- * - both sslMode and dialect are set
8
- * - the automatic 'preferred' sslMode is resolved to the most appropriate value
9
- */
10
- export default function preprocessOptions(uriOrOptions: ConnectionOptions): Promise<ConnectionOptionsObj>;
11
- //# sourceMappingURL=preprocess.d.ts.map
@@ -1,50 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const index_1 = __importDefault(require("./index"));
7
- const utils_1 = require("./utils");
8
- async function resolveSslMode(uriOrOptions) {
9
- // Try to connect with the different sslModes in order of preference
10
- if (uriOrOptions.sslMode === 'preferred') {
11
- // When NODE_TLS_REJECT_UNAUTHORIZED is set to 0, we skip the 'verify' mode, as we know it will
12
- // always work locally, but not when deploying to another environment.
13
- const modes = ['verify', 'required', 'disabled'];
14
- if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0')
15
- modes.shift();
16
- let error;
17
- for (const sslMode of modes) {
18
- try {
19
- // eslint-disable-next-line no-await-in-loop
20
- const sequelize = await (0, index_1.default)({ ...uriOrOptions, sslMode });
21
- await sequelize.close(); // eslint-disable-line no-await-in-loop
22
- return sslMode;
23
- }
24
- catch (e) {
25
- error = e;
26
- }
27
- }
28
- throw error;
29
- }
30
- return uriOrOptions.sslMode ?? 'manual';
31
- }
32
- /**
33
- * Preprocess connection options.
34
- * Allows to speed up the connection process by avoiding attempts to connect to the database.
35
- *
36
- * It ensures that
37
- * - both sslMode and dialect are set
38
- * - the automatic 'preferred' sslMode is resolved to the most appropriate value
39
- */
40
- async function preprocessOptions(uriOrOptions) {
41
- // Extract sanitized dialect and uri from the connection options
42
- const dialect = (0, utils_1.getDialect)(uriOrOptions);
43
- const uri = (0, utils_1.getUri)(uriOrOptions, dialect);
44
- // Create a new object with the sanitized dialect and uri and resolve the sslMode
45
- const obj = typeof uriOrOptions === 'string' ? { uri, dialect } : { ...uriOrOptions, uri, dialect };
46
- const sslMode = await resolveSslMode(obj);
47
- return { ...obj, sslMode };
48
- }
49
- exports.default = preprocessOptions;
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlcHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25uZWN0aW9uL3ByZXByb2Nlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxvREFBOEI7QUFDOUIsbUNBQTZDO0FBRTdDLEtBQUssVUFBVSxjQUFjLENBQUMsWUFBa0M7SUFDOUQsb0VBQW9FO0lBQ3BFLElBQUksWUFBWSxDQUFDLE9BQU8sS0FBSyxXQUFXLEVBQUU7UUFDeEMsK0ZBQStGO1FBQy9GLHNFQUFzRTtRQUN0RSxNQUFNLEtBQUssR0FBRyxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFjLENBQUM7UUFDOUQsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixLQUFLLEdBQUc7WUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFcEUsSUFBSSxLQUFZLENBQUM7UUFFakIsS0FBSyxNQUFNLE9BQU8sSUFBSSxLQUFLLEVBQUU7WUFDM0IsSUFBSTtnQkFDRiw0Q0FBNEM7Z0JBQzVDLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBQSxlQUFPLEVBQUMsRUFBRSxHQUFHLFlBQVksRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUM5RCxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLHVDQUF1QztnQkFFaEUsT0FBTyxPQUFPLENBQUM7YUFDaEI7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDVixLQUFLLEdBQUcsQ0FBQyxDQUFDO2FBQ1g7U0FDRjtRQUVELE1BQU0sS0FBSyxDQUFDO0tBQ2I7SUFFRCxPQUFPLFlBQVksQ0FBQyxPQUFPLElBQUksUUFBUSxDQUFDO0FBQzFDLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ1ksS0FBSyxVQUFVLGlCQUFpQixDQUM3QyxZQUErQjtJQUUvQixnRUFBZ0U7SUFDaEUsTUFBTSxPQUFPLEdBQUcsSUFBQSxrQkFBVSxFQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sR0FBRyxHQUFHLElBQUEsY0FBTSxFQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztJQUUxQyxpRkFBaUY7SUFDakYsTUFBTSxHQUFHLEdBQ1AsT0FBTyxZQUFZLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLFlBQVksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDMUYsTUFBTSxPQUFPLEdBQUcsTUFBTSxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFMUMsT0FBTyxFQUFFLEdBQUcsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQzdCLENBQUM7QUFiRCxvQ0FhQyJ9
@@ -1,16 +0,0 @@
1
- import { ConnectionOptionsObj } from '../types';
2
- export default class ReverseProxy {
3
- private readonly errors;
4
- private readonly server;
5
- private readonly connectedClients;
6
- readonly destination: ConnectionOptionsObj;
7
- constructor(destination: ConnectionOptionsObj);
8
- start(): Promise<void>;
9
- stop(): Promise<void>;
10
- get connectionOptions(): ConnectionOptionsObj;
11
- get error(): Error | null;
12
- private get destinationHost();
13
- private get destinationPort();
14
- private onConnection;
15
- }
16
- //# sourceMappingURL=reverse-proxy.d.ts.map
@@ -1,109 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const net_1 = __importDefault(require("net"));
7
- const socks_1 = require("socks");
8
- class ReverseProxy {
9
- constructor(destination) {
10
- this.errors = [];
11
- this.connectedClients = new Set();
12
- this.destination = destination;
13
- this.server = net_1.default.createServer(this.onConnection.bind(this));
14
- if (!this.destinationPort)
15
- throw new Error('Port is required');
16
- if (!this.destinationHost)
17
- throw new Error('Host is required');
18
- }
19
- start() {
20
- return new Promise((resolve, reject) => {
21
- this.server.on('error', reject);
22
- this.server.listen(0, '127.0.0.1', resolve);
23
- });
24
- }
25
- stop() {
26
- return new Promise((resolve, reject) => {
27
- this.server.close(e => {
28
- if (e)
29
- reject(e);
30
- else
31
- resolve();
32
- });
33
- this.connectedClients.forEach(client => client.destroy());
34
- });
35
- }
36
- get connectionOptions() {
37
- const { address, port } = this.server.address();
38
- const connection = { ...this.destination };
39
- if (this.destination.uri) {
40
- const uri = new URL(this.destination.uri);
41
- uri.host = address;
42
- uri.port = port.toString();
43
- connection.uri = uri.toString();
44
- }
45
- connection.host = address;
46
- connection.port = port;
47
- return connection;
48
- }
49
- get error() {
50
- return this.errors.length > 0 ? this.errors[0] : null;
51
- }
52
- get destinationHost() {
53
- return this.destination.uri ? new URL(this.destination.uri).hostname : this.destination.host;
54
- }
55
- get destinationPort() {
56
- // Use port from object or uri if provided
57
- if (this.destination.port)
58
- return this.destination.port;
59
- if (this.destination.uri && new URL(this.destination.uri).port)
60
- return Number(new URL(this.destination.uri).port);
61
- // Use default port for known dialects otherwise
62
- if (this.destination.dialect === 'postgres')
63
- return 5432;
64
- if (this.destination.dialect === 'mysql' || this.destination.dialect === 'mariadb')
65
- return 3306;
66
- if (this.destination.dialect === 'mssql')
67
- return 1433;
68
- // Otherwise throw an error
69
- throw new Error('Port is required');
70
- }
71
- async onConnection(socket) {
72
- let socks5Proxy;
73
- this.connectedClients.add(socket);
74
- socket.on('error', error => {
75
- this.errors.push(error);
76
- if (!socket.closed) {
77
- socket.destroy(error);
78
- }
79
- });
80
- socket.on('close', () => {
81
- this.connectedClients.delete(socket);
82
- if (!socks5Proxy?.socket.closed) {
83
- socks5Proxy?.socket.destroy();
84
- }
85
- });
86
- try {
87
- socks5Proxy = await socks_1.SocksClient.createConnection({
88
- proxy: { ...this.destination.proxySocks, type: 5 },
89
- command: 'connect',
90
- destination: { host: this.destinationHost, port: this.destinationPort },
91
- timeout: 4000,
92
- });
93
- socks5Proxy.socket.on('close', () => {
94
- this.connectedClients.delete(socks5Proxy.socket);
95
- if (!socket.closed) {
96
- socket.destroy();
97
- }
98
- });
99
- socks5Proxy.socket.on('error', socket.destroy);
100
- socks5Proxy.socket.pipe(socket);
101
- socket.pipe(socks5Proxy.socket);
102
- }
103
- catch (err) {
104
- socket.destroy(err);
105
- }
106
- }
107
- }
108
- exports.default = ReverseProxy;
109
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmV2ZXJzZS1wcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25uZWN0aW9uL3JldmVyc2UtcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4Q0FBc0I7QUFDdEIsaUNBQW9DO0FBS3BDLE1BQXFCLFlBQVk7SUFNL0IsWUFBWSxXQUFpQztRQUw1QixXQUFNLEdBQVksRUFBRSxDQUFDO1FBRXJCLHFCQUFnQixHQUFvQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSTdELElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsYUFBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWU7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELEtBQUs7UUFDSCxPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUk7UUFDRixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNwQixJ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
@@ -1,10 +0,0 @@
1
- import type { ConnectionOptions } from '../types';
2
- import type { Logger } from '@forestadmin/datasource-toolkit';
3
- import { Dialect } from 'sequelize';
4
- import { SslMode } from '../types';
5
- export declare function getUri(uriOrOptions: ConnectionOptions, dialect: Dialect): string | null;
6
- export declare function getDialect(uriOrOptions: ConnectionOptions): Dialect;
7
- export declare function getSchema(uri: string): string;
8
- export declare function getLogger(logger: Logger): (sql: string) => void;
9
- export declare function getSslConfiguration(dialect: Dialect, sslMode: SslMode, servername?: string, logger?: Logger): Record<string, unknown>;
10
- //# sourceMappingURL=utils.d.ts.map
@@ -1,106 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSslConfiguration = exports.getLogger = exports.getSchema = exports.getDialect = exports.getUri = void 0;
4
- const errors_1 = require("./errors");
5
- function checkUri(uri) {
6
- if (!/.*:\/\//g.test(uri) && uri !== 'sqlite::memory:') {
7
- throw new errors_1.DatabaseConnectError(`Connection Uri "${uri}" provided to SQL data source is not valid.` +
8
- ' Should be <dialect>://<connection>.');
9
- }
10
- }
11
- function getUri(uriOrOptions, dialect) {
12
- const uri = typeof uriOrOptions === 'string' ? uriOrOptions : uriOrOptions.uri;
13
- if (uri) {
14
- checkUri(uri);
15
- const url = new URL(uri);
16
- url.protocol = dialect;
17
- return url.toString();
18
- }
19
- return null;
20
- }
21
- exports.getUri = getUri;
22
- function getDialect(uriOrOptions) {
23
- let dialect;
24
- if (typeof uriOrOptions !== 'string' && uriOrOptions.dialect) {
25
- dialect = uriOrOptions.dialect;
26
- }
27
- else if (typeof uriOrOptions === 'string' || uriOrOptions.uri) {
28
- const uri = typeof uriOrOptions === 'string' ? uriOrOptions : uriOrOptions.uri;
29
- checkUri(uri);
30
- dialect = new URL(uri).protocol.slice(0, -1);
31
- }
32
- else {
33
- throw new errors_1.DatabaseConnectError('Expected dialect to be provided in options or uri.');
34
- }
35
- if (dialect === 'mysql2')
36
- return 'mysql';
37
- if (dialect === 'tedious')
38
- return 'mssql';
39
- if (dialect === 'pg' || dialect === 'postgresql')
40
- return 'postgres';
41
- return dialect;
42
- }
43
- exports.getDialect = getDialect;
44
- function getSchema(uri) {
45
- return uri ? new URL(uri).searchParams.get('schema') : null;
46
- }
47
- exports.getSchema = getSchema;
48
- function getLogger(logger) {
49
- return (sql) => logger?.('Debug', sql.substring(sql.indexOf(':') + 2));
50
- }
51
- exports.getLogger = getLogger;
52
- function getSslConfiguration(dialect, sslMode, servername, logger) {
53
- switch (dialect) {
54
- case 'mariadb':
55
- if (sslMode === 'disabled')
56
- return { ssl: false };
57
- if (sslMode === 'required')
58
- return { ssl: { rejectUnauthorized: false } };
59
- if (sslMode === 'verify')
60
- return { ssl: true };
61
- break;
62
- case 'mssql':
63
- if (sslMode === 'disabled')
64
- return { options: { encrypt: false } };
65
- if (sslMode === 'required')
66
- return { options: { encrypt: true, trustServerCertificate: true } };
67
- if (sslMode === 'verify')
68
- return { options: { encrypt: true, trustServerCertificate: false } };
69
- break;
70
- case 'mysql':
71
- if (sslMode === 'disabled')
72
- return { ssl: false };
73
- if (sslMode === 'required')
74
- return { ssl: { rejectUnauthorized: false } };
75
- if (sslMode === 'verify')
76
- return { ssl: { rejectUnauthorized: true } };
77
- break;
78
- case 'postgres':
79
- if (sslMode === 'disabled')
80
- return { ssl: false };
81
- // Pass servername to the net.tlsSocket constructor.
82
- // This is done so that
83
- // - Certificate verification still work when using a proxy server to reach the db (we are
84
- // forced to use a tcp reverse proxy because some drivers do not support them)
85
- // - Providers which use SNI to route requests to the correct database still work (most
86
- // notably neon.tech).
87
- // Note that we should either do that for the other vendors (if possible), or
88
- // replace the reverse proxy by a forward proxy (when supported).
89
- if (sslMode === 'required')
90
- return { ssl: { require: true, rejectUnauthorized: false, servername } };
91
- if (sslMode === 'verify')
92
- return { ssl: { require: true, rejectUnauthorized: true, servername } };
93
- break;
94
- case 'db2':
95
- case 'oracle':
96
- case 'snowflake':
97
- case 'sqlite':
98
- default:
99
- if (sslMode && sslMode !== 'manual') {
100
- logger?.('Warn', `ignoring sslMode=${sslMode} (not supported for ${dialect})`);
101
- }
102
- return {};
103
- }
104
- }
105
- exports.getSslConfiguration = getSslConfiguration;
106
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29ubmVjdGlvbi91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFLQSxxQ0FBZ0Q7QUFHaEQsU0FBUyxRQUFRLENBQUMsR0FBVztJQUMzQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLEtBQUssaUJBQWlCLEVBQUU7UUFDdEQsTUFBTSxJQUFJLDZCQUFvQixDQUM1QixtQkFBbUIsR0FBRyw2Q0FBNkM7WUFDakUsc0NBQXNDLENBQ3pDLENBQUM7S0FDSDtBQUNILENBQUM7QUFFRCxTQUFnQixNQUFNLENBQUMsWUFBK0IsRUFBRSxPQUFnQjtJQUN0RSxNQUFNLEdBQUcsR0FBRyxPQUFPLFlBQVksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztJQUUvRSxJQUFJLEdBQUcsRUFBRTtRQUNQLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVkLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLEdBQUcsQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBRXZCLE9BQU8sR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDO0tBQ3ZCO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBYkQsd0JBYUM7QUFFRCxTQUFnQixVQUFVLENBQUMsWUFBK0I7SUFDeEQsSUFBSSxPQUFlLENBQUM7SUFFcEIsSUFBSSxPQUFPLFlBQVksS0FBSyxRQUFRLElBQUksWUFBWSxDQUFDLE9BQU8sRUFBRTtRQUM1RCxPQUFPLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQztLQUNoQztTQUFNLElBQUksT0FBTyxZQUFZLEtBQUssUUFBUSxJQUFJLFlBQVksQ0FBQyxHQUFHLEVBQUU7UUFDL0QsTUFBTSxHQUFHLEdBQUcsT0FBTyxZQUFZ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