@tmlmobilidade/databases 20260323.400.54

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 (57) hide show
  1. package/dist/clients/go-clickhouse.d.ts +30 -0
  2. package/dist/clients/go-clickhouse.js +110 -0
  3. package/dist/clients/go-mongo.d.ts +30 -0
  4. package/dist/clients/go-mongo.js +117 -0
  5. package/dist/clients/index.d.ts +5 -0
  6. package/dist/clients/index.js +5 -0
  7. package/dist/clients/pcgidb-ticketing.d.ts +30 -0
  8. package/dist/clients/pcgidb-ticketing.js +117 -0
  9. package/dist/clients/pcgidb-validations.d.ts +29 -0
  10. package/dist/clients/pcgidb-validations.js +116 -0
  11. package/dist/clients/rawdb.d.ts +29 -0
  12. package/dist/clients/rawdb.js +116 -0
  13. package/dist/index.d.ts +4 -0
  14. package/dist/index.js +4 -0
  15. package/dist/interfaces/index.d.ts +2 -0
  16. package/dist/interfaces/index.js +2 -0
  17. package/dist/interfaces/simplified-apex/index.d.ts +4 -0
  18. package/dist/interfaces/simplified-apex/index.js +4 -0
  19. package/dist/interfaces/simplified-apex/simplified-apex-locations.d.ts +38 -0
  20. package/dist/interfaces/simplified-apex/simplified-apex-locations.js +57 -0
  21. package/dist/interfaces/simplified-apex/simplified-apex-on-board-refunds.d.ts +48 -0
  22. package/dist/interfaces/simplified-apex/simplified-apex-on-board-refunds.js +67 -0
  23. package/dist/interfaces/simplified-apex/simplified-apex-on-board-sales.d.ts +49 -0
  24. package/dist/interfaces/simplified-apex/simplified-apex-on-board-sales.js +68 -0
  25. package/dist/interfaces/simplified-apex/simplified-apex-validations.d.ts +47 -0
  26. package/dist/interfaces/simplified-apex/simplified-apex-validations.js +67 -0
  27. package/dist/interfaces/simplified-vehicle-events/index.d.ts +1 -0
  28. package/dist/interfaces/simplified-vehicle-events/index.js +1 -0
  29. package/dist/interfaces/simplified-vehicle-events/simplified-vehicle-events.d.ts +39 -0
  30. package/dist/interfaces/simplified-vehicle-events/simplified-vehicle-events.js +61 -0
  31. package/dist/templates/clickhouse.d.ts +107 -0
  32. package/dist/templates/clickhouse.js +201 -0
  33. package/dist/types/clickhouse/column.d.ts +36 -0
  34. package/dist/types/clickhouse/column.js +2 -0
  35. package/dist/types/clickhouse/data-types.d.ts +5 -0
  36. package/dist/types/clickhouse/data-types.js +1 -0
  37. package/dist/types/clickhouse/index.d.ts +3 -0
  38. package/dist/types/clickhouse/index.js +3 -0
  39. package/dist/types/clickhouse/table-engines.d.ts +7 -0
  40. package/dist/types/clickhouse/table-engines.js +1 -0
  41. package/dist/types/index.d.ts +1 -0
  42. package/dist/types/index.js +1 -0
  43. package/dist/utils/get-clickhouse-param-type.d.ts +7 -0
  44. package/dist/utils/get-clickhouse-param-type.js +16 -0
  45. package/dist/utils/index.d.ts +3 -0
  46. package/dist/utils/index.js +3 -0
  47. package/dist/utils/prepare-named-query-params.d.ts +16 -0
  48. package/dist/utils/prepare-named-query-params.js +47 -0
  49. package/dist/utils/prepare-positional-query-params.d.ts +13 -0
  50. package/dist/utils/prepare-positional-query-params.js +36 -0
  51. package/dist/utils/query-from-file.d.ts +17 -0
  52. package/dist/utils/query-from-file.js +42 -0
  53. package/dist/utils/query-from-string.d.ts +14 -0
  54. package/dist/utils/query-from-string.js +31 -0
  55. package/dist/utils/validate-sql-param.d.ts +12 -0
  56. package/dist/utils/validate-sql-param.js +23 -0
  57. package/package.json +53 -0
@@ -0,0 +1,30 @@
1
+ import { ClickHouseClient } from '@clickhouse/client';
2
+ export declare class GOClickHouseClient {
3
+ private static _instance;
4
+ private client;
5
+ private tunnel;
6
+ /**
7
+ * Disallow direct instantiation of the service.
8
+ * Use getClient() instead to ensure singleton behavior.
9
+ */
10
+ private constructor();
11
+ /**
12
+ * Returns the singleton instance of the subclass.
13
+ */
14
+ static getClient(): Promise<ClickHouseClient>;
15
+ /**
16
+ * Connects to ClickHouse, setting up the client instance.
17
+ * If SSH tunneling is required, it establishes the tunnel first.
18
+ * This method is called internally by the service and should not be used directly.
19
+ */
20
+ private connect;
21
+ /**
22
+ * Constructs the connection string based on environment variables
23
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
24
+ * connections, validating the necessary environment variables for each case.
25
+ * This method is called internally by the service and should not be used directly.
26
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
27
+ * @returns A promise that resolves to the ClickHouse connection string.
28
+ */
29
+ private getConnectionString;
30
+ }
@@ -0,0 +1,110 @@
1
+ /* * */
2
+ import { createClient } from '@clickhouse/client';
3
+ import { Logger } from '@tmlmobilidade/logger';
4
+ import { SshTunnelService } from '@tmlmobilidade/ssh';
5
+ /* * */
6
+ export class GOClickHouseClient {
7
+ //
8
+ static _instance = null;
9
+ client;
10
+ tunnel = null;
11
+ /**
12
+ * Disallow direct instantiation of the service.
13
+ * Use getClient() instead to ensure singleton behavior.
14
+ */
15
+ constructor() { }
16
+ /**
17
+ * Returns the singleton instance of the subclass.
18
+ */
19
+ static async getClient() {
20
+ // If no instance exists, create one and store the promise.
21
+ // This ensures that if multiple calls to getClient() happen concurrently,
22
+ // they will all await the same initialization process.
23
+ if (!this._instance) {
24
+ this._instance = (async () => {
25
+ const instance = new GOClickHouseClient();
26
+ // This behaves like the constructor,
27
+ // but allows for async initialization.
28
+ await instance.connect();
29
+ return instance;
30
+ })();
31
+ }
32
+ // Await the instance if it's still initializing,
33
+ // or return it immediately if ready.
34
+ const instance = await this._instance;
35
+ return instance.client;
36
+ }
37
+ /**
38
+ * Connects to ClickHouse, setting up the client instance.
39
+ * If SSH tunneling is required, it establishes the tunnel first.
40
+ * This method is called internally by the service and should not be used directly.
41
+ */
42
+ async connect() {
43
+ Logger.info('Connecting to GOClickHouseClient...');
44
+ const connectionString = await this.getConnectionString();
45
+ this.client = createClient({ url: connectionString });
46
+ }
47
+ /**
48
+ * Constructs the connection string based on environment variables
49
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
50
+ * connections, validating the necessary environment variables for each case.
51
+ * This method is called internally by the service and should not be used directly.
52
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
53
+ * @returns A promise that resolves to the ClickHouse connection string.
54
+ */
55
+ async getConnectionString() {
56
+ //
57
+ //
58
+ // Validate required environment variables
59
+ if (process.env.GODB_CLICKHOUSE_TUNNEL_ENABLED !== 'true' && process.env.GODB_CLICKHOUSE_TUNNEL_ENABLED !== 'false') {
60
+ throw new Error('Missing GODB_CLICKHOUSE_TUNNEL_ENABLED. Please indicate whether SSH tunneling is required by setting GODB_CLICKHOUSE_TUNNEL_ENABLED to "true" or "false".');
61
+ }
62
+ if (!process.env.GODB_CLICKHOUSE_HOST || !process.env.GODB_CLICKHOUSE_PORT) {
63
+ throw new Error('Missing GODB_CLICKHOUSE_HOST or GODB_CLICKHOUSE_PORT');
64
+ }
65
+ if (process.env.GODB_CLICKHOUSE_TUNNEL_ENABLED === 'false') {
66
+ return `http://${process.env.GODB_CLICKHOUSE_USER}:${process.env.GODB_CLICKHOUSE_PASSWORD}@${process.env.GODB_CLICKHOUSE_HOST}:${process.env.GODB_CLICKHOUSE_PORT}`;
67
+ }
68
+ // SSH required
69
+ if (!process.env.GODB_CLICKHOUSE_TUNNEL_LOCAL_PORT) {
70
+ throw new Error('Missing GODB_CLICKHOUSE_TUNNEL_LOCAL_PORT');
71
+ }
72
+ if (!process.env.GODB_CLICKHOUSE_TUNNEL_SSH_HOST || !process.env.GODB_CLICKHOUSE_TUNNEL_SSH_USERNAME) {
73
+ throw new Error('Missing SSH config');
74
+ }
75
+ const sshConfig = {
76
+ forwardOptions: {
77
+ dstAddr: process.env.GODB_CLICKHOUSE_HOST,
78
+ dstPort: Number(process.env.GODB_CLICKHOUSE_PORT),
79
+ srcAddr: 'localhost',
80
+ srcPort: Number(process.env.GODB_CLICKHOUSE_TUNNEL_LOCAL_PORT),
81
+ },
82
+ serverOptions: {
83
+ port: Number(process.env.GODB_CLICKHOUSE_TUNNEL_LOCAL_PORT),
84
+ },
85
+ sshOptions: {
86
+ agent: process.env.SSH_AUTH_SOCK,
87
+ host: process.env.GODB_CLICKHOUSE_TUNNEL_SSH_HOST,
88
+ keepaliveCountMax: 3,
89
+ keepaliveInterval: 10_000,
90
+ port: 22,
91
+ username: process.env.GODB_CLICKHOUSE_TUNNEL_SSH_USERNAME,
92
+ },
93
+ tunnelOptions: {
94
+ autoClose: false,
95
+ reconnectOnError: true,
96
+ },
97
+ };
98
+ const sshOptions = {
99
+ maxRetries: 3,
100
+ };
101
+ this.tunnel = new SshTunnelService(sshConfig, sshOptions);
102
+ Logger.info('[GOClickHouseClient] Setting up SSH Tunnel...');
103
+ const connection = await this.tunnel.connect();
104
+ const addr = connection.address();
105
+ if (!addr || typeof addr !== 'object') {
106
+ throw new Error('[GOClickHouseClient] Failed to retrieve SSH tunnel address.');
107
+ }
108
+ return `http://${process.env.GODB_CLICKHOUSE_USER}:${process.env.GODB_CLICKHOUSE_PASSWORD}@localhost:${addr.port}`;
109
+ }
110
+ }
@@ -0,0 +1,30 @@
1
+ import { MongoClient } from 'mongodb';
2
+ export declare class GOMongoClient {
3
+ private static _instance;
4
+ private client;
5
+ private tunnel;
6
+ /**
7
+ * Disallow direct instantiation of the service.
8
+ * Use getClient() instead to ensure singleton behavior.
9
+ */
10
+ private constructor();
11
+ /**
12
+ * Returns the singleton instance of the subclass.
13
+ */
14
+ static getClient(): Promise<MongoClient>;
15
+ /**
16
+ * Connects to Mongo, setting up the client instance.
17
+ * If SSH tunneling is required, it establishes the tunnel first.
18
+ * This method is called internally by the service and should not be used directly.
19
+ */
20
+ private connect;
21
+ /**
22
+ * Constructs the connection string based on environment variables
23
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
24
+ * connections, validating the necessary environment variables for each case.
25
+ * This method is called internally by the service and should not be used directly.
26
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
27
+ * @returns A promise that resolves to the Mongo connection string.
28
+ */
29
+ private getConnectionString;
30
+ }
@@ -0,0 +1,117 @@
1
+ /* * */
2
+ import { Logger } from '@tmlmobilidade/logger';
3
+ import { SshTunnelService } from '@tmlmobilidade/ssh';
4
+ import { MongoClient } from 'mongodb';
5
+ /* * */
6
+ export class GOMongoClient {
7
+ //
8
+ static _instance = null;
9
+ client;
10
+ tunnel = null;
11
+ /**
12
+ * Disallow direct instantiation of the service.
13
+ * Use getClient() instead to ensure singleton behavior.
14
+ */
15
+ constructor() { }
16
+ /**
17
+ * Returns the singleton instance of the subclass.
18
+ */
19
+ static async getClient() {
20
+ // If no instance exists, create one and store the promise.
21
+ // This ensures that if multiple calls to getClient() happen concurrently,
22
+ // they will all await the same initialization process.
23
+ if (!this._instance) {
24
+ this._instance = (async () => {
25
+ const instance = new GOMongoClient();
26
+ // This behaves like the constructor,
27
+ // but allows for async initialization.
28
+ await instance.connect();
29
+ return instance;
30
+ })();
31
+ }
32
+ // Await the instance if it's still initializing,
33
+ // or return it immediately if ready.
34
+ const instance = await this._instance;
35
+ return instance.client;
36
+ }
37
+ /**
38
+ * Connects to Mongo, setting up the client instance.
39
+ * If SSH tunneling is required, it establishes the tunnel first.
40
+ * This method is called internally by the service and should not be used directly.
41
+ */
42
+ async connect() {
43
+ Logger.info('Connecting to GOMongoClient...');
44
+ const connectionString = await this.getConnectionString();
45
+ this.client = new MongoClient(connectionString);
46
+ this.client.on('close', () => {
47
+ console.warn('[GOMongoClient] Database connection closed unexpectedly.');
48
+ });
49
+ this.client.on('reconnect', () => {
50
+ console.log('[GOMongoClient] Database reconnected.');
51
+ });
52
+ await this.client.connect();
53
+ }
54
+ /**
55
+ * Constructs the connection string based on environment variables
56
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
57
+ * connections, validating the necessary environment variables for each case.
58
+ * This method is called internally by the service and should not be used directly.
59
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
60
+ * @returns A promise that resolves to the Mongo connection string.
61
+ */
62
+ async getConnectionString() {
63
+ //
64
+ //
65
+ // Validate required environment variables
66
+ if (process.env.GODB_MONGO_TUNNEL_ENABLED !== 'true' && process.env.GODB_MONGO_TUNNEL_ENABLED !== 'false') {
67
+ throw new Error('Missing GODB_MONGO_TUNNEL_ENABLED. Please indicate whether SSH tunneling is required by setting GODB_MONGO_TUNNEL_ENABLED to "true" or "false".');
68
+ }
69
+ if (!process.env.GODB_MONGO_HOST || !process.env.GODB_MONGO_PORT) {
70
+ throw new Error('Missing GODB_MONGO_HOST or GODB_MONGO_PORT');
71
+ }
72
+ if (process.env.GODB_MONGO_TUNNEL_ENABLED === 'false') {
73
+ return `mongodb://${process.env.GODB_MONGO_USER}:${process.env.GODB_MONGO_PASSWORD}@${process.env.GODB_MONGO_HOST}:${process.env.GODB_MONGO_PORT}`;
74
+ }
75
+ // SSH required
76
+ if (!process.env.GODB_MONGO_TUNNEL_LOCAL_PORT) {
77
+ throw new Error('Missing GODB_MONGO_TUNNEL_LOCAL_PORT');
78
+ }
79
+ if (!process.env.GODB_MONGO_TUNNEL_SSH_HOST || !process.env.GODB_MONGO_TUNNEL_SSH_USERNAME) {
80
+ throw new Error('Missing SSH config');
81
+ }
82
+ const sshConfig = {
83
+ forwardOptions: {
84
+ dstAddr: process.env.GODB_MONGO_HOST,
85
+ dstPort: Number(process.env.GODB_MONGO_PORT),
86
+ srcAddr: 'localhost',
87
+ srcPort: Number(process.env.GODB_MONGO_TUNNEL_LOCAL_PORT),
88
+ },
89
+ serverOptions: {
90
+ port: Number(process.env.GODB_MONGO_TUNNEL_LOCAL_PORT),
91
+ },
92
+ sshOptions: {
93
+ agent: process.env.SSH_AUTH_SOCK,
94
+ host: process.env.GODB_MONGO_TUNNEL_SSH_HOST,
95
+ keepaliveCountMax: 3,
96
+ keepaliveInterval: 10_000,
97
+ port: 22,
98
+ username: process.env.GODB_MONGO_TUNNEL_SSH_USERNAME,
99
+ },
100
+ tunnelOptions: {
101
+ autoClose: false,
102
+ reconnectOnError: true,
103
+ },
104
+ };
105
+ const sshOptions = {
106
+ maxRetries: 3,
107
+ };
108
+ this.tunnel = new SshTunnelService(sshConfig, sshOptions);
109
+ Logger.info('[GOMongoClient] Setting up SSH Tunnel...');
110
+ const connection = await this.tunnel.connect();
111
+ const addr = connection.address();
112
+ if (!addr || typeof addr !== 'object') {
113
+ throw new Error('[GOMongoClient] Failed to retrieve SSH tunnel address.');
114
+ }
115
+ return `mongodb://${process.env.GODB_MONGO_USER}:${process.env.GODB_MONGO_PASSWORD}@localhost:${addr.port}`;
116
+ }
117
+ }
@@ -0,0 +1,5 @@
1
+ export * from './go-clickhouse.js';
2
+ export * from './go-mongo.js';
3
+ export * from './pcgidb-ticketing.js';
4
+ export * from './pcgidb-validations.js';
5
+ export * from './rawdb.js';
@@ -0,0 +1,5 @@
1
+ export * from './go-clickhouse.js';
2
+ export * from './go-mongo.js';
3
+ export * from './pcgidb-ticketing.js';
4
+ export * from './pcgidb-validations.js';
5
+ export * from './rawdb.js';
@@ -0,0 +1,30 @@
1
+ import { MongoClient } from 'mongodb';
2
+ export declare class PCGIDBTicketingService {
3
+ private static _instance;
4
+ private client;
5
+ private tunnel;
6
+ /**
7
+ * Disallow direct instantiation of the service.
8
+ * Use getClient() instead to ensure singleton behavior.
9
+ */
10
+ private constructor();
11
+ /**
12
+ * Returns the singleton instance of the subclass.
13
+ */
14
+ static getClient(): Promise<MongoClient>;
15
+ /**
16
+ * Connects to Mongo, setting up the client instance.
17
+ * If SSH tunneling is required, it establishes the tunnel first.
18
+ * This method is called internally by the service and should not be used directly.
19
+ */
20
+ private connect;
21
+ /**
22
+ * Constructs the connection string based on environment variables
23
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
24
+ * connections, validating the necessary environment variables for each case.
25
+ * This method is called internally by the service and should not be used directly.
26
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
27
+ * @returns A promise that resolves to the Mongo connection string.
28
+ */
29
+ private getConnectionString;
30
+ }
@@ -0,0 +1,117 @@
1
+ /* * */
2
+ import { Logger } from '@tmlmobilidade/logger';
3
+ import { SshTunnelService } from '@tmlmobilidade/ssh';
4
+ import { MongoClient } from 'mongodb';
5
+ /* * */
6
+ export class PCGIDBTicketingService {
7
+ //
8
+ static _instance = null;
9
+ client;
10
+ tunnel = null;
11
+ /**
12
+ * Disallow direct instantiation of the service.
13
+ * Use getClient() instead to ensure singleton behavior.
14
+ */
15
+ constructor() { }
16
+ /**
17
+ * Returns the singleton instance of the subclass.
18
+ */
19
+ static async getClient() {
20
+ // If no instance exists, create one and store the promise.
21
+ // This ensures that if multiple calls to getClient() happen concurrently,
22
+ // they will all await the same initialization process.
23
+ if (!this._instance) {
24
+ this._instance = (async () => {
25
+ const instance = new PCGIDBTicketingService();
26
+ // This behaves like the constructor,
27
+ // but allows for async initialization.
28
+ await instance.connect();
29
+ return instance;
30
+ })();
31
+ }
32
+ // Await the instance if it's still initializing,
33
+ // or return it immediately if ready.
34
+ const instance = await this._instance;
35
+ return instance.client;
36
+ }
37
+ /**
38
+ * Connects to Mongo, setting up the client instance.
39
+ * If SSH tunneling is required, it establishes the tunnel first.
40
+ * This method is called internally by the service and should not be used directly.
41
+ */
42
+ async connect() {
43
+ Logger.info('Connecting to PCGIDBTicketingService...');
44
+ const connectionString = await this.getConnectionString();
45
+ this.client = new MongoClient(connectionString);
46
+ this.client.on('close', () => {
47
+ console.warn('[PCGIDBTicketingService] Database connection closed unexpectedly.');
48
+ });
49
+ this.client.on('reconnect', () => {
50
+ console.log('[PCGIDBTicketingService] Database reconnected.');
51
+ });
52
+ await this.client.connect();
53
+ }
54
+ /**
55
+ * Constructs the connection string based on environment variables
56
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
57
+ * connections, validating the necessary environment variables for each case.
58
+ * This method is called internally by the service and should not be used directly.
59
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
60
+ * @returns A promise that resolves to the Mongo connection string.
61
+ */
62
+ async getConnectionString() {
63
+ //
64
+ //
65
+ // Validate required environment variables
66
+ if (process.env.PCGI_MONGO_DB_TUNNEL_ENABLED !== 'true' && process.env.PCGI_MONGO_DB_TUNNEL_ENABLED !== 'false') {
67
+ throw new Error('Missing PCGI_MONGO_DB_TUNNEL_ENABLED. Please indicate whether SSH tunneling is required by setting PCGI_MONGO_DB_TUNNEL_ENABLED to "true" or "false".');
68
+ }
69
+ if (!process.env.PCGI_MONGO_DB_HOST || !process.env.PCGI_MONGO_DB_PORT) {
70
+ throw new Error('Missing PCGI_MONGO_DB_HOST or PCGI_MONGO_DB_PORT');
71
+ }
72
+ if (process.env.PCGI_MTicketingONGO_DB_TUNNEL_ENABLED === 'false') {
73
+ return `http://${process.env.PCGI_MTicketingONGO_DB_USER}:${process.env.PCGI_MTicketingONGO_DB_PASSWORD}@${process.env.PCGI_MTicketingONGO_DB_HOST}:${process.env.PCGI_MTicketingONGO_DB_PORT}`;
74
+ }
75
+ // SSH required
76
+ if (!process.env.PCGI_MTicketingONGO_DB_TUNNEL_LOCAL_PORT) {
77
+ throw new Error('Missing PCGI_MTicketingONGO_DB_TUNNEL_LOCAL_PORT');
78
+ }
79
+ if (!process.env.PCGI_MTicketingONGO_DB_TUNNEL_SSH_HOST || !process.env.PCGI_MTicketingONGO_DB_TUNNEL_SSH_USERNAME) {
80
+ throw new Error('Missing SSH config');
81
+ }
82
+ const sshConfig = {
83
+ forwardOptions: {
84
+ dstAddr: process.env.PCGI_MTicketingONGO_DB_HOST,
85
+ dstPort: Number(process.env.PCGI_MTicketingONGO_DB_PORT),
86
+ srcAddr: 'localhost',
87
+ srcPort: Number(process.env.PCGI_MTicketingONGO_DB_TUNNEL_LOCAL_PORT),
88
+ },
89
+ serverOptions: {
90
+ port: Number(process.env.PCGI_MTicketingONGO_DB_TUNNEL_LOCAL_PORT),
91
+ },
92
+ sshOptions: {
93
+ agent: process.env.SSH_AUTH_SOCK,
94
+ host: process.env.PCGI_MTicketingONGO_DB_TUNNEL_SSH_HOST,
95
+ keepaliveCountMax: 3,
96
+ keepaliveInterval: 10_000,
97
+ port: 22,
98
+ username: process.env.PCGI_MTicketingONGO_DB_TUNNEL_SSH_USERNAME,
99
+ },
100
+ tunnelOptions: {
101
+ autoClose: false,
102
+ reconnectOnError: true,
103
+ },
104
+ };
105
+ const sshOptions = {
106
+ maxRetries: 3,
107
+ };
108
+ this.tunnel = new SshTunnelService(sshConfig, sshOptions);
109
+ Logger.info('[PCGIDBTicketingService] Setting up SSH Tunnel...');
110
+ const connection = await this.tunnel.connect();
111
+ const addr = connection.address();
112
+ if (!addr || typeof addr !== 'object') {
113
+ throw new Error('[PCGIDBTicketingService] Failed to retrieve SSH tunnel address.');
114
+ }
115
+ return `http://${process.env.PCGI_MTicketingONGO_DB_USER}:${process.env.PCGI_MTicketingONGO_DB_PASSWORD}@localhost:${addr.port}`;
116
+ }
117
+ }
@@ -0,0 +1,29 @@
1
+ export declare class PCGIDBValidationsService {
2
+ private static _instance;
3
+ private client;
4
+ private tunnel;
5
+ /**
6
+ * Disallow direct instantiation of the service.
7
+ * Use getInstance() instead to ensure singleton behavior.
8
+ */
9
+ private constructor();
10
+ /**
11
+ * Returns the singleton instance of the subclass.
12
+ */
13
+ static getInstance(): Promise<PCGIDBValidationsService>;
14
+ /**
15
+ * Connects to Mongo, setting up the client instance.
16
+ * If SSH tunneling is required, it establishes the tunnel first.
17
+ * This method is called internally by the service and should not be used directly.
18
+ */
19
+ private connect;
20
+ /**
21
+ * Constructs the connection string based on environment variables
22
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
23
+ * connections, validating the necessary environment variables for each case.
24
+ * This method is called internally by the service and should not be used directly.
25
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
26
+ * @returns A promise that resolves to the Mongo connection string.
27
+ */
28
+ private getConnectionString;
29
+ }
@@ -0,0 +1,116 @@
1
+ /* * */
2
+ import { Logger } from '@tmlmobilidade/logger';
3
+ import { SshTunnelService } from '@tmlmobilidade/ssh';
4
+ import { MongoClient } from 'mongodb';
5
+ /* * */
6
+ export class PCGIDBValidationsService {
7
+ //
8
+ static _instance = null;
9
+ client;
10
+ tunnel = null;
11
+ /**
12
+ * Disallow direct instantiation of the service.
13
+ * Use getInstance() instead to ensure singleton behavior.
14
+ */
15
+ constructor() { }
16
+ /**
17
+ * Returns the singleton instance of the subclass.
18
+ */
19
+ static async getInstance() {
20
+ // If no instance exists, create one and store the promise.
21
+ // This ensures that if multiple calls to getInstance() happen concurrently,
22
+ // they will all await the same initialization process.
23
+ if (!this._instance) {
24
+ this._instance = (async () => {
25
+ const instance = new PCGIDBValidationsService();
26
+ // This behaves like the constructor,
27
+ // but allows for async initialization.
28
+ await instance.connect();
29
+ return instance;
30
+ })();
31
+ }
32
+ // Await the instance if it's still initializing,
33
+ // or return it immediately if ready.
34
+ return this._instance;
35
+ }
36
+ /**
37
+ * Connects to Mongo, setting up the client instance.
38
+ * If SSH tunneling is required, it establishes the tunnel first.
39
+ * This method is called internally by the service and should not be used directly.
40
+ */
41
+ async connect() {
42
+ Logger.info('Connecting to PCGIDBValidationsService...');
43
+ const connectionString = await this.getConnectionString();
44
+ this.client = new MongoClient(connectionString);
45
+ this.client.on('close', () => {
46
+ console.warn('[PCGIDBValidationsService] Database connection closed unexpectedly.');
47
+ });
48
+ this.client.on('reconnect', () => {
49
+ console.log('[PCGIDBValidationsService] Database reconnected.');
50
+ });
51
+ await this.client.connect();
52
+ }
53
+ /**
54
+ * Constructs the connection string based on environment variables
55
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
56
+ * connections, validating the necessary environment variables for each case.
57
+ * This method is called internally by the service and should not be used directly.
58
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
59
+ * @returns A promise that resolves to the Mongo connection string.
60
+ */
61
+ async getConnectionString() {
62
+ //
63
+ //
64
+ // Validate required environment variables
65
+ if (process.env.PCGI_MONGO_DB_TUNNEL_ENABLED !== 'true' && process.env.PCGI_MONGO_DB_TUNNEL_ENABLED !== 'false') {
66
+ throw new Error('Missing PCGI_MONGO_DB_TUNNEL_ENABLED. Please indicate whether SSH tunneling is required by setting PCGI_MONGO_DB_TUNNEL_ENABLED to "true" or "false".');
67
+ }
68
+ if (!process.env.PCGI_MONGO_DB_HOST || !process.env.PCGI_MONGO_DB_PORT) {
69
+ throw new Error('Missing PCGI_MONGO_DB_HOST or PCGI_MONGO_DB_PORT');
70
+ }
71
+ if (process.env.PCGI_MValidationsONGO_DB_TUNNEL_ENABLED === 'false') {
72
+ return `http://${process.env.PCGI_MValidationsONGO_DB_USER}:${process.env.PCGI_MValidationsONGO_DB_PASSWORD}@${process.env.PCGI_MValidationsONGO_DB_HOST}:${process.env.PCGI_MValidationsONGO_DB_PORT}`;
73
+ }
74
+ // SSH required
75
+ if (!process.env.PCGI_MValidationsONGO_DB_TUNNEL_LOCAL_PORT) {
76
+ throw new Error('Missing PCGI_MValidationsONGO_DB_TUNNEL_LOCAL_PORT');
77
+ }
78
+ if (!process.env.PCGI_MValidationsONGO_DB_TUNNEL_SSH_HOST || !process.env.PCGI_MValidationsONGO_DB_TUNNEL_SSH_USERNAME) {
79
+ throw new Error('Missing SSH config');
80
+ }
81
+ const sshConfig = {
82
+ forwardOptions: {
83
+ dstAddr: process.env.PCGI_MValidationsONGO_DB_HOST,
84
+ dstPort: Number(process.env.PCGI_MValidationsONGO_DB_PORT),
85
+ srcAddr: 'localhost',
86
+ srcPort: Number(process.env.PCGI_MValidationsONGO_DB_TUNNEL_LOCAL_PORT),
87
+ },
88
+ serverOptions: {
89
+ port: Number(process.env.PCGI_MValidationsONGO_DB_TUNNEL_LOCAL_PORT),
90
+ },
91
+ sshOptions: {
92
+ agent: process.env.SSH_AUTH_SOCK,
93
+ host: process.env.PCGI_MValidationsONGO_DB_TUNNEL_SSH_HOST,
94
+ keepaliveCountMax: 3,
95
+ keepaliveInterval: 10_000,
96
+ port: 22,
97
+ username: process.env.PCGI_MValidationsONGO_DB_TUNNEL_SSH_USERNAME,
98
+ },
99
+ tunnelOptions: {
100
+ autoClose: false,
101
+ reconnectOnError: true,
102
+ },
103
+ };
104
+ const sshOptions = {
105
+ maxRetries: 3,
106
+ };
107
+ this.tunnel = new SshTunnelService(sshConfig, sshOptions);
108
+ Logger.info('[PCGIDBValidationsService] Setting up SSH Tunnel...');
109
+ const connection = await this.tunnel.connect();
110
+ const addr = connection.address();
111
+ if (!addr || typeof addr !== 'object') {
112
+ throw new Error('[PCGIDBValidationsService] Failed to retrieve SSH tunnel address.');
113
+ }
114
+ return `http://${process.env.PCGI_MValidationsONGO_DB_USER}:${process.env.PCGI_MValidationsONGO_DB_PASSWORD}@localhost:${addr.port}`;
115
+ }
116
+ }
@@ -0,0 +1,29 @@
1
+ export declare class RAWDBService {
2
+ private static _instance;
3
+ private client;
4
+ private tunnel;
5
+ /**
6
+ * Disallow direct instantiation of the service.
7
+ * Use getInstance() instead to ensure singleton behavior.
8
+ */
9
+ private constructor();
10
+ /**
11
+ * Returns the singleton instance of the subclass.
12
+ */
13
+ static getInstance(): Promise<RAWDBService>;
14
+ /**
15
+ * Connects to Mongo, setting up the client instance.
16
+ * If SSH tunneling is required, it establishes the tunnel first.
17
+ * This method is called internally by the service and should not be used directly.
18
+ */
19
+ private connect;
20
+ /**
21
+ * Constructs the connection string based on environment variables
22
+ * and SSH tunneling configuration, and handles both direct connections and SSH-tunneled
23
+ * connections, validating the necessary environment variables for each case.
24
+ * This method is called internally by the service and should not be used directly.
25
+ * @throws Will throw an error if required environment variables are missing or if the SSH tunnel setup fails.
26
+ * @returns A promise that resolves to the Mongo connection string.
27
+ */
28
+ private getConnectionString;
29
+ }