opticedge-cloud-utils 1.0.13 → 1.0.15

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,4 @@
1
+ import { Db, Collection, Document } from 'mongodb';
2
+ export declare function connectToMongo2(projectId: string, uriSecret: string): Promise<void>;
3
+ export declare function getDb2(dbName: string): Db;
4
+ export declare function getCollection2<T extends Document = Document>(dbName: string, collectionName: string): Collection<T>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.connectToMongo2 = connectToMongo2;
4
+ exports.getDb2 = getDb2;
5
+ exports.getCollection2 = getCollection2;
6
+ // Multi DB safe util
7
+ const mongodb_1 = require("mongodb");
8
+ const secrets_1 = require("../utils/secrets");
9
+ let client;
10
+ let connectPromise;
11
+ async function connectToMongo2(projectId, uriSecret) {
12
+ if (client)
13
+ return; // already connected
14
+ if (!connectPromise) {
15
+ connectPromise = (async () => {
16
+ const uri = await (0, secrets_1.getSecret)(projectId, uriSecret);
17
+ client = new mongodb_1.MongoClient(uri);
18
+ await client.connect();
19
+ })();
20
+ }
21
+ await connectPromise;
22
+ }
23
+ function getDb2(dbName) {
24
+ if (!client)
25
+ throw new Error('Mongo not initialized');
26
+ return client.db(dbName);
27
+ }
28
+ function getCollection2(dbName, collectionName) {
29
+ return getDb2(dbName).collection(collectionName);
30
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const mongo2_1 = require("./mongo2");
37
+ const mongodb_1 = require("mongodb");
38
+ const secretsModule = __importStar(require("../utils/secrets"));
39
+ jest.mock('mongodb');
40
+ jest.mock('../utils/secrets');
41
+ const mockDb = {
42
+ collection: jest.fn()
43
+ };
44
+ const mockConnect = jest.fn();
45
+ const mockClient = {
46
+ connect: mockConnect,
47
+ db: jest.fn().mockReturnValue(mockDb)
48
+ };
49
+ beforeEach(() => {
50
+ jest.clearAllMocks();
51
+ secretsModule.getSecret.mockResolvedValue('mongodb://mock-uri');
52
+ mongodb_1.MongoClient.mockImplementation(() => mockClient);
53
+ });
54
+ describe('Mongo Utils', () => {
55
+ it('should connect to MongoDB and store client', async () => {
56
+ await (0, mongo2_1.connectToMongo2)('test-project', 'mongo-uri-secret');
57
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', 'mongo-uri-secret');
58
+ expect(mockConnect).toHaveBeenCalled();
59
+ });
60
+ it('should return a Db instance when client is initialized', async () => {
61
+ await (0, mongo2_1.connectToMongo2)('test-project', 'mongo-uri-secret');
62
+ const db = (0, mongo2_1.getDb2)('test-db');
63
+ expect(mockClient.db).toHaveBeenCalledWith('test-db');
64
+ expect(db).toBe(mockDb);
65
+ });
66
+ it('should return a collection when client is initialized', async () => {
67
+ await (0, mongo2_1.connectToMongo2)('test-project', 'mongo-uri-secret');
68
+ (0, mongo2_1.getCollection2)('test-db', 'users');
69
+ expect(mockClient.db).toHaveBeenCalledWith('test-db');
70
+ expect(mockDb.collection).toHaveBeenCalledWith('users');
71
+ });
72
+ it('should throw error if client is not initialized (getDb)', () => {
73
+ jest.isolateModules(() => {
74
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
75
+ const { getDb2 } = require('./mongo2');
76
+ expect(() => getDb2('test-db')).toThrow('Mongo not initialized');
77
+ });
78
+ });
79
+ it('should throw error if client is not initialized (getCollection)', () => {
80
+ jest.isolateModules(() => {
81
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
82
+ const { getCollection2 } = require('./mongo2');
83
+ expect(() => getCollection2('test-db', 'users')).toThrow('Mongo not initialized');
84
+ });
85
+ });
86
+ });
@@ -0,0 +1,6 @@
1
+ import { MongoClient, Db, Collection, Document } from 'mongodb';
2
+ export declare function connectToMongo3(projectId: string, uriSecret: string): Promise<MongoClient>;
3
+ export declare function getDb3(uriSecret: string, dbName: string): Db;
4
+ export declare function getCollection3<T extends Document = Document>(uriSecret: string, dbName: string, collectionName: string): Collection<T>;
5
+ export declare const __mongoClients: Map<string, MongoClient>;
6
+ export declare const __connectPromises: Map<string, Promise<void>>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.__connectPromises = exports.__mongoClients = void 0;
4
+ exports.connectToMongo3 = connectToMongo3;
5
+ exports.getDb3 = getDb3;
6
+ exports.getCollection3 = getCollection3;
7
+ // Multi cluster safe util
8
+ const mongodb_1 = require("mongodb");
9
+ const secrets_1 = require("../utils/secrets");
10
+ const clients = new Map();
11
+ const connectPromises = new Map();
12
+ async function connectToMongo3(projectId, uriSecret) {
13
+ if (clients.has(uriSecret)) {
14
+ return clients.get(uriSecret);
15
+ }
16
+ if (!connectPromises.has(uriSecret)) {
17
+ const promise = (async () => {
18
+ const uri = await (0, secrets_1.getSecret)(projectId, uriSecret);
19
+ const client = new mongodb_1.MongoClient(uri);
20
+ await client.connect();
21
+ clients.set(uriSecret, client);
22
+ })();
23
+ connectPromises.set(uriSecret, promise);
24
+ }
25
+ await connectPromises.get(uriSecret);
26
+ return clients.get(uriSecret);
27
+ }
28
+ function getDb3(uriSecret, dbName) {
29
+ const client = clients.get(uriSecret);
30
+ if (!client) {
31
+ throw new Error(`Mongo client for secret "${uriSecret}" not initialized`);
32
+ }
33
+ return client.db(dbName);
34
+ }
35
+ function getCollection3(uriSecret, dbName, collectionName) {
36
+ return getDb3(uriSecret, dbName).collection(collectionName);
37
+ }
38
+ exports.__mongoClients = clients;
39
+ exports.__connectPromises = connectPromises;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const mongo3_1 = require("./mongo3");
37
+ const mongodb_1 = require("mongodb");
38
+ const secretsModule = __importStar(require("../utils/secrets"));
39
+ jest.mock('mongodb');
40
+ jest.mock('../utils/secrets');
41
+ const mockDb = {
42
+ collection: jest.fn()
43
+ };
44
+ const mockConnect = jest.fn();
45
+ const mockClient = {
46
+ connect: mockConnect,
47
+ db: jest.fn().mockReturnValue(mockDb)
48
+ };
49
+ beforeEach(() => {
50
+ jest.clearAllMocks();
51
+ mongo3_1.__mongoClients.clear();
52
+ mongo3_1.__connectPromises.clear();
53
+ secretsModule.getSecret.mockResolvedValue('mongodb://mock-uri');
54
+ mongodb_1.MongoClient.mockImplementation(() => mockClient);
55
+ });
56
+ describe('MongoClientManager (multi-cluster)', () => {
57
+ const clusterASecret = 'clusterA-uri-secret';
58
+ const clusterBSecret = 'clusterB-uri-secret';
59
+ it('should connect and cache client for a single cluster', async () => {
60
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterASecret);
61
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterASecret);
62
+ expect(mockConnect).toHaveBeenCalled();
63
+ const db = (0, mongo3_1.getDb3)(clusterASecret, 'test-db');
64
+ expect(mockClient.db).toHaveBeenCalledWith('test-db');
65
+ expect(db).toBe(mockDb);
66
+ });
67
+ it('should reuse client if already connected', async () => {
68
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterASecret);
69
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterASecret);
70
+ // getSecret and connect should only happen once
71
+ expect(secretsModule.getSecret).toHaveBeenCalledTimes(1);
72
+ expect(mockConnect).toHaveBeenCalledTimes(1);
73
+ });
74
+ it('should connect and cache separate clients for multiple clusters', async () => {
75
+ // Mock different URIs for 2 clusters
76
+ ;
77
+ secretsModule.getSecret
78
+ .mockResolvedValueOnce('mongodb://mock-uri-A')
79
+ .mockResolvedValueOnce('mongodb://mock-uri-B');
80
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterASecret);
81
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterBSecret);
82
+ // Should call getSecret + connect twice (for 2 clusters)
83
+ expect(secretsModule.getSecret).toHaveBeenCalledTimes(2);
84
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterASecret);
85
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterBSecret);
86
+ expect(mockConnect).toHaveBeenCalledTimes(2);
87
+ });
88
+ it('should return a collection when client is initialized', async () => {
89
+ await (0, mongo3_1.connectToMongo3)('test-project', clusterASecret);
90
+ (0, mongo3_1.getCollection3)(clusterASecret, 'test-db', 'users');
91
+ expect(mockClient.db).toHaveBeenCalledWith('test-db');
92
+ expect(mockDb.collection).toHaveBeenCalledWith('users');
93
+ });
94
+ it('should throw error if client not initialized (getDb)', () => {
95
+ jest.isolateModules(() => {
96
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
97
+ const { getDb3 } = require('./mongo3');
98
+ expect(() => getDb3('unknown-uri-secret', 'some-db')).toThrow('Mongo client for secret "unknown-uri-secret" not initialized');
99
+ });
100
+ });
101
+ it('should throw error if client not initialized (getCollection)', () => {
102
+ jest.isolateModules(() => {
103
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
104
+ const { getCollection3 } = require('./mongo3');
105
+ expect(() => getCollection3('unknown-uri-secret', 'some-db', 'users')).toThrow('Mongo client for secret "unknown-uri-secret" not initialized');
106
+ });
107
+ });
108
+ });
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './auth/verify';
2
2
  export * from './db/mongo';
3
+ export * from './db/mongo2';
4
+ export * from './db/mongo3';
3
5
  export * from './types/pokemontcg';
4
6
  export * from './utils/env';
5
7
  export * from './utils/secrets';
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./auth/verify"), exports);
18
18
  __exportStar(require("./db/mongo"), exports);
19
+ __exportStar(require("./db/mongo2"), exports);
20
+ __exportStar(require("./db/mongo3"), exports);
19
21
  __exportStar(require("./types/pokemontcg"), exports);
20
22
  __exportStar(require("./utils/env"), exports);
21
23
  __exportStar(require("./utils/secrets"), exports);
@@ -122,7 +122,7 @@ export type PokemonTCGCard = {
122
122
  export type PokemonPriceHistory = {
123
123
  _id: string;
124
124
  card_id: string;
125
- card_num: string;
125
+ card_data: Partial<PokemonTCGCard>;
126
126
  pricehistory: [
127
127
  {
128
128
  date: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opticedge-cloud-utils",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "Common utilities for cloud functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,63 @@
1
+ import { connectToMongo2, getDb2, getCollection2 } from './mongo2'
2
+ import { MongoClient, Db } from 'mongodb'
3
+ import * as secretsModule from '../utils/secrets'
4
+
5
+ jest.mock('mongodb')
6
+ jest.mock('../utils/secrets')
7
+
8
+ const mockDb = {
9
+ collection: jest.fn()
10
+ } as unknown as Db
11
+
12
+ const mockConnect = jest.fn()
13
+ const mockClient = {
14
+ connect: mockConnect,
15
+ db: jest.fn().mockReturnValue(mockDb)
16
+ } as unknown as MongoClient
17
+
18
+ beforeEach(() => {
19
+ jest.clearAllMocks()
20
+ ;(secretsModule.getSecret as jest.Mock).mockResolvedValue('mongodb://mock-uri')
21
+ ;(MongoClient as unknown as jest.Mock).mockImplementation(() => mockClient)
22
+ })
23
+
24
+ describe('Mongo Utils', () => {
25
+ it('should connect to MongoDB and store client', async () => {
26
+ await connectToMongo2('test-project', 'mongo-uri-secret')
27
+
28
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', 'mongo-uri-secret')
29
+ expect(mockConnect).toHaveBeenCalled()
30
+ })
31
+
32
+ it('should return a Db instance when client is initialized', async () => {
33
+ await connectToMongo2('test-project', 'mongo-uri-secret')
34
+
35
+ const db = getDb2('test-db')
36
+ expect(mockClient.db).toHaveBeenCalledWith('test-db')
37
+ expect(db).toBe(mockDb)
38
+ })
39
+
40
+ it('should return a collection when client is initialized', async () => {
41
+ await connectToMongo2('test-project', 'mongo-uri-secret')
42
+
43
+ getCollection2('test-db', 'users')
44
+ expect(mockClient.db).toHaveBeenCalledWith('test-db')
45
+ expect(mockDb.collection).toHaveBeenCalledWith('users')
46
+ })
47
+
48
+ it('should throw error if client is not initialized (getDb)', () => {
49
+ jest.isolateModules(() => {
50
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
51
+ const { getDb2 } = require('./mongo2')
52
+ expect(() => getDb2('test-db')).toThrow('Mongo not initialized')
53
+ })
54
+ })
55
+
56
+ it('should throw error if client is not initialized (getCollection)', () => {
57
+ jest.isolateModules(() => {
58
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
59
+ const { getCollection2 } = require('./mongo2')
60
+ expect(() => getCollection2('test-db', 'users')).toThrow('Mongo not initialized')
61
+ })
62
+ })
63
+ })
@@ -0,0 +1,32 @@
1
+ // Multi DB safe util
2
+ import { MongoClient, Db, Collection, Document } from 'mongodb'
3
+ import { getSecret } from '../utils/secrets'
4
+
5
+ let client: MongoClient
6
+ let connectPromise: Promise<void> | undefined
7
+
8
+ export async function connectToMongo2(projectId: string, uriSecret: string) {
9
+ if (client) return // already connected
10
+
11
+ if (!connectPromise) {
12
+ connectPromise = (async () => {
13
+ const uri = await getSecret(projectId, uriSecret)
14
+ client = new MongoClient(uri)
15
+ await client.connect()
16
+ })()
17
+ }
18
+
19
+ await connectPromise
20
+ }
21
+
22
+ export function getDb2(dbName: string): Db {
23
+ if (!client) throw new Error('Mongo not initialized')
24
+ return client.db(dbName)
25
+ }
26
+
27
+ export function getCollection2<T extends Document = Document>(
28
+ dbName: string,
29
+ collectionName: string
30
+ ): Collection<T> {
31
+ return getDb2(dbName).collection<T>(collectionName)
32
+ }
@@ -0,0 +1,100 @@
1
+ import {
2
+ connectToMongo3,
3
+ getDb3,
4
+ getCollection3,
5
+ __mongoClients,
6
+ __connectPromises
7
+ } from './mongo3'
8
+ import { MongoClient, Db } from 'mongodb'
9
+ import * as secretsModule from '../utils/secrets'
10
+
11
+ jest.mock('mongodb')
12
+ jest.mock('../utils/secrets')
13
+
14
+ const mockDb = {
15
+ collection: jest.fn()
16
+ } as unknown as Db
17
+
18
+ const mockConnect = jest.fn()
19
+ const mockClient = {
20
+ connect: mockConnect,
21
+ db: jest.fn().mockReturnValue(mockDb)
22
+ } as unknown as MongoClient
23
+
24
+ beforeEach(() => {
25
+ jest.clearAllMocks()
26
+ __mongoClients.clear()
27
+ __connectPromises.clear()
28
+ ;(secretsModule.getSecret as jest.Mock).mockResolvedValue('mongodb://mock-uri')
29
+ ;(MongoClient as unknown as jest.Mock).mockImplementation(() => mockClient)
30
+ })
31
+
32
+ describe('MongoClientManager (multi-cluster)', () => {
33
+ const clusterASecret = 'clusterA-uri-secret'
34
+ const clusterBSecret = 'clusterB-uri-secret'
35
+
36
+ it('should connect and cache client for a single cluster', async () => {
37
+ await connectToMongo3('test-project', clusterASecret)
38
+
39
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterASecret)
40
+ expect(mockConnect).toHaveBeenCalled()
41
+
42
+ const db = getDb3(clusterASecret, 'test-db')
43
+ expect(mockClient.db).toHaveBeenCalledWith('test-db')
44
+ expect(db).toBe(mockDb)
45
+ })
46
+
47
+ it('should reuse client if already connected', async () => {
48
+ await connectToMongo3('test-project', clusterASecret)
49
+ await connectToMongo3('test-project', clusterASecret)
50
+
51
+ // getSecret and connect should only happen once
52
+ expect(secretsModule.getSecret).toHaveBeenCalledTimes(1)
53
+ expect(mockConnect).toHaveBeenCalledTimes(1)
54
+ })
55
+
56
+ it('should connect and cache separate clients for multiple clusters', async () => {
57
+ // Mock different URIs for 2 clusters
58
+ ;(secretsModule.getSecret as jest.Mock)
59
+ .mockResolvedValueOnce('mongodb://mock-uri-A')
60
+ .mockResolvedValueOnce('mongodb://mock-uri-B')
61
+
62
+ await connectToMongo3('test-project', clusterASecret)
63
+ await connectToMongo3('test-project', clusterBSecret)
64
+
65
+ // Should call getSecret + connect twice (for 2 clusters)
66
+ expect(secretsModule.getSecret).toHaveBeenCalledTimes(2)
67
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterASecret)
68
+ expect(secretsModule.getSecret).toHaveBeenCalledWith('test-project', clusterBSecret)
69
+ expect(mockConnect).toHaveBeenCalledTimes(2)
70
+ })
71
+
72
+ it('should return a collection when client is initialized', async () => {
73
+ await connectToMongo3('test-project', clusterASecret)
74
+
75
+ getCollection3(clusterASecret, 'test-db', 'users')
76
+
77
+ expect(mockClient.db).toHaveBeenCalledWith('test-db')
78
+ expect(mockDb.collection).toHaveBeenCalledWith('users')
79
+ })
80
+
81
+ it('should throw error if client not initialized (getDb)', () => {
82
+ jest.isolateModules(() => {
83
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
84
+ const { getDb3 } = require('./mongo3')
85
+ expect(() => getDb3('unknown-uri-secret', 'some-db')).toThrow(
86
+ 'Mongo client for secret "unknown-uri-secret" not initialized'
87
+ )
88
+ })
89
+ })
90
+
91
+ it('should throw error if client not initialized (getCollection)', () => {
92
+ jest.isolateModules(() => {
93
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
94
+ const { getCollection3 } = require('./mongo3')
95
+ expect(() => getCollection3('unknown-uri-secret', 'some-db', 'users')).toThrow(
96
+ 'Mongo client for secret "unknown-uri-secret" not initialized'
97
+ )
98
+ })
99
+ })
100
+ })
@@ -0,0 +1,47 @@
1
+ // Multi cluster safe util
2
+ import { MongoClient, Db, Collection, Document } from 'mongodb'
3
+ import { getSecret } from '../utils/secrets'
4
+
5
+ const clients: Map<string, MongoClient> = new Map()
6
+ const connectPromises: Map<string, Promise<void>> = new Map()
7
+
8
+ export async function connectToMongo3(projectId: string, uriSecret: string): Promise<MongoClient> {
9
+ if (clients.has(uriSecret)) {
10
+ return clients.get(uriSecret)!
11
+ }
12
+
13
+ if (!connectPromises.has(uriSecret)) {
14
+ const promise = (async () => {
15
+ const uri = await getSecret(projectId, uriSecret)
16
+ const client = new MongoClient(uri)
17
+ await client.connect()
18
+ clients.set(uriSecret, client)
19
+ })()
20
+
21
+ connectPromises.set(uriSecret, promise)
22
+ }
23
+
24
+ await connectPromises.get(uriSecret)!
25
+
26
+ return clients.get(uriSecret)!
27
+ }
28
+
29
+ export function getDb3(uriSecret: string, dbName: string): Db {
30
+ const client = clients.get(uriSecret)
31
+ if (!client) {
32
+ throw new Error(`Mongo client for secret "${uriSecret}" not initialized`)
33
+ }
34
+
35
+ return client.db(dbName)
36
+ }
37
+
38
+ export function getCollection3<T extends Document = Document>(
39
+ uriSecret: string,
40
+ dbName: string,
41
+ collectionName: string
42
+ ): Collection<T> {
43
+ return getDb3(uriSecret, dbName).collection<T>(collectionName)
44
+ }
45
+
46
+ export const __mongoClients = clients
47
+ export const __connectPromises = connectPromises
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './auth/verify'
2
2
  export * from './db/mongo'
3
+ export * from './db/mongo2'
4
+ export * from './db/mongo3'
3
5
  export * from './types/pokemontcg'
4
6
  export * from './utils/env'
5
7
  export * from './utils/secrets'
@@ -125,7 +125,7 @@ export type PokemonTCGCard = {
125
125
  export type PokemonPriceHistory = {
126
126
  _id: string
127
127
  card_id: string
128
- card_num: string
128
+ card_data: Partial<PokemonTCGCard>
129
129
  pricehistory: [
130
130
  {
131
131
  date: string