@ido_kawaz/mongo-client 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +36 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/mongoClient.test.d.ts +2 -0
- package/dist/__tests__/mongoClient.test.d.ts.map +1 -0
- package/dist/__tests__/mongoClient.test.js +89 -0
- package/dist/__tests__/mongoClient.test.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +23 -0
- package/dist/config.js.map +1 -0
- package/dist/dal.d.ts +6 -0
- package/dist/dal.d.ts.map +1 -0
- package/dist/dal.js +10 -0
- package/dist/dal.js.map +1 -0
- package/dist/errors.d.ts +4 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +10 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/mongoClient.d.ts +13 -0
- package/dist/mongoClient.d.ts.map +1 -0
- package/dist/mongoClient.js +33 -0
- package/dist/mongoClient.js.map +1 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# mongo-client
|
|
2
|
+
Lightweight MongoDB client helper for Node.js services using Mongoose.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
```bash
|
|
6
|
+
npm i @ido_kawaz/mongo-client
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Environment Variables
|
|
10
|
+
- `MONGO_CONNECTION_STRING` (required): MongoDB connection URI.
|
|
11
|
+
- `MONGO_CONNECTION_TIMEOUT_MS` (optional): server selection timeout in milliseconds. Default is `5000`.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
```ts
|
|
15
|
+
import { MongoClient, Schema, createMongoConfig } from "@ido_kawaz/mongo-client";
|
|
16
|
+
|
|
17
|
+
type User = {
|
|
18
|
+
email: string;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const config = createMongoConfig();
|
|
23
|
+
const mongoClient = new MongoClient(config);
|
|
24
|
+
|
|
25
|
+
const userSchema = new Schema<User>({
|
|
26
|
+
email: { type: String, required: true, unique: true },
|
|
27
|
+
createdAt: { type: Date, required: true },
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
async function bootstrap() {
|
|
31
|
+
await mongoClient.start();
|
|
32
|
+
|
|
33
|
+
const userModel = mongoClient.createModel<User>("User", userSchema);
|
|
34
|
+
await mongoClient.ensureIndexes([userModel]);
|
|
35
|
+
|
|
36
|
+
// Use your model or pass it into your DAL layer.
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function shutdown() {
|
|
40
|
+
await mongoClient.stop();
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
- `createMongoConfig()`: reads and validates MongoDB config from environment variables.
|
|
46
|
+
- `new MongoClient(config)`: creates a Mongoose connection wrapper.
|
|
47
|
+
- `start()`: opens and validates the MongoDB connection.
|
|
48
|
+
- `createModel<T>(name, schema)`: creates and returns a typed model.
|
|
49
|
+
- `ensureIndexes(models)`: ensures indexes for all provided models.
|
|
50
|
+
- `stop()`: closes the active MongoDB connection.
|
|
51
|
+
|
|
52
|
+
## Tests
|
|
53
|
+
```bash
|
|
54
|
+
npx jest --runInBand
|
|
55
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_1 = require("../config");
|
|
4
|
+
describe("createMongoConfig", () => {
|
|
5
|
+
const originalEnv = process.env;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
process.env = { ...originalEnv };
|
|
8
|
+
delete process.env.MONGO_CONNECTION_STRING;
|
|
9
|
+
delete process.env.MONGO_CONNECTION_TIMEOUT_MS;
|
|
10
|
+
});
|
|
11
|
+
afterAll(() => {
|
|
12
|
+
process.env = originalEnv;
|
|
13
|
+
});
|
|
14
|
+
it("returns parsed config when env vars are valid", () => {
|
|
15
|
+
process.env.MONGO_CONNECTION_STRING = "mongodb://localhost:27017/my-db";
|
|
16
|
+
process.env.MONGO_CONNECTION_TIMEOUT_MS = "7000";
|
|
17
|
+
const config = (0, config_1.createMongoConfig)();
|
|
18
|
+
expect(config).toEqual({
|
|
19
|
+
mongoConnectionString: "mongodb://localhost:27017/my-db",
|
|
20
|
+
mongoConnectionTimeoutMS: 7000,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
it("uses default timeout when timeout env var is missing", () => {
|
|
24
|
+
process.env.MONGO_CONNECTION_STRING = "mongodb://localhost:27017/my-db";
|
|
25
|
+
const config = (0, config_1.createMongoConfig)();
|
|
26
|
+
expect(config.mongoConnectionTimeoutMS).toBe(5000);
|
|
27
|
+
});
|
|
28
|
+
it("throws when connection string is missing", () => {
|
|
29
|
+
expect(() => (0, config_1.createMongoConfig)()).toThrow("Invalid MongoDB configuration");
|
|
30
|
+
});
|
|
31
|
+
it("throws when connection string is not a URI", () => {
|
|
32
|
+
process.env.MONGO_CONNECTION_STRING = "not-a-uri";
|
|
33
|
+
expect(() => (0, config_1.createMongoConfig)()).toThrow("Invalid MongoDB configuration");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":";;AAAA,sCAA8C;AAE9C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAEhC,UAAU,CAAC,GAAG,EAAE;QACZ,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;QAC3C,OAAO,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,GAAG,EAAE;QACV,OAAO,CAAC,GAAG,GAAG,WAAW,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,iCAAiC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,MAAM,CAAC;QAEjD,MAAM,MAAM,GAAG,IAAA,0BAAiB,GAAE,CAAC;QAEnC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACnB,qBAAqB,EAAE,iCAAiC;YACxD,wBAAwB,EAAE,IAAI;SACjC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,iCAAiC,CAAC;QAExE,MAAM,MAAM,GAAG,IAAA,0BAAiB,GAAE,CAAC;QAEnC,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,0BAAiB,GAAE,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QAClD,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,WAAW,CAAC;QAElD,MAAM,CAAC,GAAG,EAAE,CAAC,IAAA,0BAAiB,GAAE,CAAC,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongoClient.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mongoClient.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
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 mongoose_1 = __importDefault(require("mongoose"));
|
|
7
|
+
const errors_1 = require("../errors");
|
|
8
|
+
const mongoClient_1 = require("../mongoClient");
|
|
9
|
+
jest.mock("mongoose", () => ({
|
|
10
|
+
__esModule: true,
|
|
11
|
+
default: {
|
|
12
|
+
createConnection: jest.fn(),
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
describe("MongoClient", () => {
|
|
16
|
+
const mockedMongoose = mongoose_1.default;
|
|
17
|
+
const connectionMock = {
|
|
18
|
+
asPromise: jest.fn(),
|
|
19
|
+
close: jest.fn(),
|
|
20
|
+
model: jest.fn(),
|
|
21
|
+
};
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
mockedMongoose.createConnection.mockReturnValue(connectionMock);
|
|
25
|
+
});
|
|
26
|
+
it("creates a connection with config values", () => {
|
|
27
|
+
const config = {
|
|
28
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
29
|
+
mongoConnectionTimeoutMS: 4500,
|
|
30
|
+
};
|
|
31
|
+
new mongoClient_1.MongoClient(config);
|
|
32
|
+
expect(mockedMongoose.createConnection).toHaveBeenCalledWith(config.mongoConnectionString, {
|
|
33
|
+
serverSelectionTimeoutMS: config.mongoConnectionTimeoutMS,
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
it("starts successfully when connection resolves", async () => {
|
|
37
|
+
connectionMock.asPromise.mockResolvedValue(undefined);
|
|
38
|
+
const consoleSpy = jest.spyOn(console, "log").mockImplementation(() => undefined);
|
|
39
|
+
const client = new mongoClient_1.MongoClient({
|
|
40
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
41
|
+
mongoConnectionTimeoutMS: 5000,
|
|
42
|
+
});
|
|
43
|
+
await expect(client.start()).resolves.toBeUndefined();
|
|
44
|
+
expect(connectionMock.asPromise).toHaveBeenCalledTimes(1);
|
|
45
|
+
consoleSpy.mockRestore();
|
|
46
|
+
});
|
|
47
|
+
it("throws DatabaseConnectionError when connection fails", async () => {
|
|
48
|
+
connectionMock.asPromise.mockRejectedValue(new Error("connection refused"));
|
|
49
|
+
const client = new mongoClient_1.MongoClient({
|
|
50
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
51
|
+
mongoConnectionTimeoutMS: 5000,
|
|
52
|
+
});
|
|
53
|
+
await expect(client.start()).rejects.toBeInstanceOf(errors_1.DatabaseConnectionError);
|
|
54
|
+
await expect(client.start()).rejects.toThrow("connection refused");
|
|
55
|
+
});
|
|
56
|
+
it("creates models through the underlying connection", () => {
|
|
57
|
+
const createdModel = { modelName: "User" };
|
|
58
|
+
connectionMock.model.mockReturnValue(createdModel);
|
|
59
|
+
const client = new mongoClient_1.MongoClient({
|
|
60
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
61
|
+
mongoConnectionTimeoutMS: 5000,
|
|
62
|
+
});
|
|
63
|
+
const userSchema = {};
|
|
64
|
+
const result = client.createModel("User", userSchema);
|
|
65
|
+
expect(connectionMock.model).toHaveBeenCalledWith("User", userSchema);
|
|
66
|
+
expect(result).toBe(createdModel);
|
|
67
|
+
});
|
|
68
|
+
it("ensures indexes for all provided models", async () => {
|
|
69
|
+
const modelA = { ensureIndexes: jest.fn().mockResolvedValue(undefined) };
|
|
70
|
+
const modelB = { ensureIndexes: jest.fn().mockResolvedValue(undefined) };
|
|
71
|
+
const client = new mongoClient_1.MongoClient({
|
|
72
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
73
|
+
mongoConnectionTimeoutMS: 5000,
|
|
74
|
+
});
|
|
75
|
+
await client.ensureIndexes([modelA, modelB]);
|
|
76
|
+
expect(modelA.ensureIndexes).toHaveBeenCalledTimes(1);
|
|
77
|
+
expect(modelB.ensureIndexes).toHaveBeenCalledTimes(1);
|
|
78
|
+
});
|
|
79
|
+
it("stops by closing the connection", async () => {
|
|
80
|
+
connectionMock.close.mockResolvedValue(undefined);
|
|
81
|
+
const client = new mongoClient_1.MongoClient({
|
|
82
|
+
mongoConnectionString: "mongodb://localhost:27017/test-db",
|
|
83
|
+
mongoConnectionTimeoutMS: 5000,
|
|
84
|
+
});
|
|
85
|
+
await client.stop();
|
|
86
|
+
expect(connectionMock.close).toHaveBeenCalledTimes(1);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=mongoClient.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongoClient.test.js","sourceRoot":"","sources":["../../src/__tests__/mongoClient.test.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,wBAAwB,EAAE,MAAM,CAAC;CACpC;AAYD,eAAO,MAAM,iBAAiB,QAAO,WASpC,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
exports.createMongoConfig = void 0;
|
|
7
|
+
const joi_1 = __importDefault(require("joi"));
|
|
8
|
+
const mongoEnvSchema = joi_1.default.object({
|
|
9
|
+
MONGO_CONNECTION_STRING: joi_1.default.string().uri().required(),
|
|
10
|
+
MONGO_CONNECTION_TIMEOUT_MS: joi_1.default.number().default(5000)
|
|
11
|
+
});
|
|
12
|
+
const createMongoConfig = () => {
|
|
13
|
+
const { error, value } = mongoEnvSchema.validate(process.env, { allowUnknown: true });
|
|
14
|
+
if (error) {
|
|
15
|
+
throw new Error(`Invalid MongoDB configuration: ${error.message}`);
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
mongoConnectionString: value.MONGO_CONNECTION_STRING,
|
|
19
|
+
mongoConnectionTimeoutMS: value.MONGO_CONNECTION_TIMEOUT_MS
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
exports.createMongoConfig = createMongoConfig;
|
|
23
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAAA,8CAAsB;AAYtB,MAAM,cAAc,GAAG,aAAG,CAAC,MAAM,CAAW;IACxC,uBAAuB,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACtD,2BAA2B,EAAE,aAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CAC1D,CAAC,CAAC;AAEI,MAAM,iBAAiB,GAAG,GAAgB,EAAE;IAC/C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACtF,IAAI,KAAK,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO;QACH,qBAAqB,EAAE,KAAK,CAAC,uBAAuB;QACpD,wBAAwB,EAAE,KAAK,CAAC,2BAA2B;KAC9D,CAAC;AACN,CAAC,CAAC;AATW,QAAA,iBAAiB,qBAS5B"}
|
package/dist/dal.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dal.d.ts","sourceRoot":"","sources":["../src/dal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,8BAAsB,GAAG,CAAC,CAAC;IACX,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;gBAAf,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;CAEjD"}
|
package/dist/dal.js
ADDED
package/dist/dal.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dal.js","sourceRoot":"","sources":["../src/dal.ts"],"names":[],"mappings":";;;AAEA,MAAsB,GAAG;IACrB,YAA+B,KAAe;QAAf,UAAK,GAAL,KAAK,CAAU;IAC9C,CAAC;CACJ;AAHD,kBAGC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,uBAAwB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAG9B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseConnectionError = void 0;
|
|
4
|
+
class DatabaseConnectionError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(`Database connection error:\n${message}`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.DatabaseConnectionError = DatabaseConnectionError;
|
|
10
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,uBAAwB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACvB,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;CACJ;AAJD,0DAIC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMongoConfig = exports.DatabaseConnectionError = exports.Dal = exports.Model = exports.Schema = exports.MongoClient = void 0;
|
|
4
|
+
var mongoClient_1 = require("./mongoClient");
|
|
5
|
+
Object.defineProperty(exports, "MongoClient", { enumerable: true, get: function () { return mongoClient_1.MongoClient; } });
|
|
6
|
+
var mongoose_1 = require("mongoose");
|
|
7
|
+
Object.defineProperty(exports, "Schema", { enumerable: true, get: function () { return mongoose_1.Schema; } });
|
|
8
|
+
Object.defineProperty(exports, "Model", { enumerable: true, get: function () { return mongoose_1.Model; } });
|
|
9
|
+
var dal_1 = require("./dal");
|
|
10
|
+
Object.defineProperty(exports, "Dal", { enumerable: true, get: function () { return dal_1.Dal; } });
|
|
11
|
+
var errors_1 = require("./errors");
|
|
12
|
+
Object.defineProperty(exports, "DatabaseConnectionError", { enumerable: true, get: function () { return errors_1.DatabaseConnectionError; } });
|
|
13
|
+
var config_1 = require("./config");
|
|
14
|
+
Object.defineProperty(exports, "createMongoConfig", { enumerable: true, get: function () { return config_1.createMongoConfig; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,qCAAyC;AAAhC,kGAAA,MAAM,OAAA;AAAE,iGAAA,KAAK,OAAA;AACtB,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,mCAAmD;AAA1C,iHAAA,uBAAuB,OAAA;AAChC,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Model, Schema } from "mongoose";
|
|
2
|
+
import { MongoConfig } from "./config";
|
|
3
|
+
type ModelCollection = Model<any>[];
|
|
4
|
+
export declare class MongoClient {
|
|
5
|
+
private connection;
|
|
6
|
+
constructor(config: MongoConfig);
|
|
7
|
+
ensureIndexes(models: ModelCollection): Promise<void>;
|
|
8
|
+
start(): Promise<void>;
|
|
9
|
+
stop(): Promise<void>;
|
|
10
|
+
createModel<T>(name: string, schema: Schema<T>): Model<T>;
|
|
11
|
+
}
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=mongoClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongoClient.d.ts","sourceRoot":"","sources":["../src/mongoClient.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAc,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGvC,KAAK,eAAe,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAEpC,qBAAa,WAAW;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEnB,MAAM,EAAE,WAAW;IAKzB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;CAG5D"}
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
exports.MongoClient = void 0;
|
|
7
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
|
+
const errors_1 = require("./errors");
|
|
9
|
+
class MongoClient {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
const { mongoConnectionString, mongoConnectionTimeoutMS } = config;
|
|
12
|
+
this.connection = mongoose_1.default.createConnection(mongoConnectionString, { serverSelectionTimeoutMS: mongoConnectionTimeoutMS });
|
|
13
|
+
}
|
|
14
|
+
async ensureIndexes(models) {
|
|
15
|
+
await Promise.all(Object.values(models).map((model) => model.ensureIndexes()));
|
|
16
|
+
}
|
|
17
|
+
async start() {
|
|
18
|
+
const startTime = Date.now();
|
|
19
|
+
await this.connection.asPromise().catch((error) => {
|
|
20
|
+
throw new errors_1.DatabaseConnectionError(error.message);
|
|
21
|
+
});
|
|
22
|
+
const endTime = Date.now();
|
|
23
|
+
console.log(`MongoDB Client started successfully in ${endTime - startTime} ms`);
|
|
24
|
+
}
|
|
25
|
+
async stop() {
|
|
26
|
+
await this.connection.close();
|
|
27
|
+
}
|
|
28
|
+
createModel(name, schema) {
|
|
29
|
+
return this.connection.model(name, schema);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.MongoClient = MongoClient;
|
|
33
|
+
//# sourceMappingURL=mongoClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongoClient.js","sourceRoot":"","sources":["../src/mongoClient.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA+D;AAE/D,qCAAmD;AAInD,MAAa,WAAW;IAGpB,YAAY,MAAmB;QAC3B,MAAM,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,GAAG,MAAM,CAAC;QACnE,IAAI,CAAC,UAAU,GAAG,kBAAQ,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAC/H,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,MAAuB;QACvC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,KAAK,CAAC,KAAK;QACP,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC9C,MAAM,IAAI,gCAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,0CAA0C,OAAO,GAAG,SAAS,KAAK,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,CAAC,IAAI;QACN,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAED,WAAW,CAAI,IAAY,EAAE,MAAiB;QAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAI,IAAI,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;CACJ;AA9BD,kCA8BC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ido_kawaz/mongo-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MongoDB client library for Kawaz Plus services",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"clean": "rimraf dist",
|
|
12
|
+
"clean:advanced": "rimraf dist node_modules package-lock.json",
|
|
13
|
+
"build": "npm run clean && tsc",
|
|
14
|
+
"build:watch": "tsc --watch",
|
|
15
|
+
"build:advanced": "npm run clean:advanced && npm i && tsc",
|
|
16
|
+
"test": "npm run build && jest --runInBand",
|
|
17
|
+
"package": "npm run build:advanced && npm publish --access public"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mongodb",
|
|
21
|
+
"database",
|
|
22
|
+
"client"
|
|
23
|
+
],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@types/joi": "^17.2.2",
|
|
28
|
+
"@types/mongoose": "^5.11.96",
|
|
29
|
+
"joi": "^18.0.2",
|
|
30
|
+
"mongoose": "^9.2.3",
|
|
31
|
+
"ramda": "^0.32.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "^30.0.0",
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"@types/ramda": "^0.31.1",
|
|
37
|
+
"jest": "^30.0.0",
|
|
38
|
+
"rimraf": "^6.1.3",
|
|
39
|
+
"ts-jest": "^29.4.6",
|
|
40
|
+
"typescript": "^5.9.3"
|
|
41
|
+
}
|
|
42
|
+
}
|