equipped 4.0.2 → 4.1.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/CHANGELOG.md +38 -0
- package/README.md +68 -0
- package/lib/cache/cache.d.ts +2 -2
- package/lib/cache/types/redis-cache.d.ts +3 -3
- package/lib/cache/types/redis-cache.js +7 -12
- package/lib/db/_instance.d.ts +39 -0
- package/lib/db/_instance.js +65 -0
- package/lib/db/debezium.d.ts +10 -0
- package/lib/db/debezium.js +11 -0
- package/lib/db/index.d.ts +2 -0
- package/lib/{mongoose → db}/index.js +0 -7
- package/lib/db/mongoose/changes.d.ts +8 -0
- package/lib/db/mongoose/changes.js +99 -0
- package/lib/db/mongoose/index.d.ts +15 -0
- package/lib/db/mongoose/index.js +73 -0
- package/lib/db/mongoose/query.d.ts +3 -0
- package/lib/{mongoose → db/mongoose}/query.js +14 -30
- package/lib/{mongoose → db}/query.d.ts +21 -24
- package/lib/db/query.js +20 -0
- package/lib/errors/customError.d.ts +1 -1
- package/lib/errors/index.d.ts +4 -4
- package/lib/errors/index.js +4 -4
- package/lib/errors/types/accessTokenExpired.js +2 -2
- package/lib/errors/types/accountNotVerifiedError.js +2 -2
- package/lib/errors/types/badRequestError.js +2 -2
- package/lib/errors/types/invalidToken.js +2 -2
- package/lib/errors/types/notAuthenticatedError.js +2 -2
- package/lib/errors/types/notAuthorizedError.js +2 -2
- package/lib/errors/types/notFoundError.js +2 -2
- package/lib/errors/types/refreshTokenMisusedError.js +2 -2
- package/lib/errors/types/validationError.js +2 -2
- package/lib/events/index.d.ts +22 -0
- package/lib/events/index.js +15 -0
- package/lib/events/kafka.d.ts +11 -0
- package/lib/events/kafka.js +85 -0
- package/lib/events/rabbit.d.ts +11 -4
- package/lib/events/rabbit.js +72 -38
- package/lib/exit.d.ts +1 -0
- package/lib/exit.js +7 -2
- package/lib/index.d.ts +4 -3
- package/lib/index.js +6 -4
- package/lib/instance/index.d.ts +24 -0
- package/lib/instance/index.js +92 -0
- package/lib/instance/settings.d.ts +26 -0
- package/lib/instance/settings.js +28 -0
- package/lib/listeners/emitter.d.ts +1 -0
- package/lib/listeners/emitter.js +20 -12
- package/lib/logger/index.d.ts +1 -4
- package/lib/logger/index.js +12 -5
- package/lib/server/app.d.ts +11 -0
- package/lib/{express → server}/app.js +12 -28
- package/lib/server/controllers/index.js +39 -0
- package/lib/{express → server}/controllers/request.d.ts +7 -3
- package/lib/server/controllers/request.js +74 -0
- package/lib/{express → server}/index.d.ts +2 -1
- package/lib/{express → server}/index.js +3 -0
- package/lib/{express/app.d.ts → server/routes.d.ts} +2 -8
- package/lib/server/routes.js +36 -0
- package/lib/utils/json.d.ts +1 -0
- package/lib/utils/json.js +12 -0
- package/lib/utils/retry.d.ts +2 -0
- package/lib/utils/retry.js +16 -0
- package/lib/utils/tokens.js +2 -2
- package/lib/validations/index.d.ts +26 -25
- package/package.json +24 -16
- package/lib/events/events.d.ts +0 -17
- package/lib/events/events.js +0 -26
- package/lib/express/controllers/index.js +0 -76
- package/lib/express/controllers/request.js +0 -48
- package/lib/instance.d.ts +0 -43
- package/lib/instance.js +0 -115
- package/lib/mongoose/changeStreams.d.ts +0 -25
- package/lib/mongoose/changeStreams.js +0 -93
- package/lib/mongoose/index.d.ts +0 -4
- package/lib/{express → server}/controllers/index.d.ts +0 -0
- package/lib/{express → server}/middlewares/errorHandler.d.ts +0 -0
- package/lib/{express → server}/middlewares/errorHandler.js +0 -0
- package/lib/{express → server}/middlewares/index.d.ts +2 -2
- package/lib/{express → server}/middlewares/index.js +2 -2
- package/lib/{express → server}/middlewares/notFoundHandler.d.ts +0 -0
- package/lib/{express → server}/middlewares/notFoundHandler.js +1 -1
- package/lib/{express → server}/middlewares/parseAuthUser.d.ts +0 -0
- package/lib/{express → server}/middlewares/parseAuthUser.js +2 -2
- /package/lib/{express → server}/middlewares/requireAuthUser.d.ts +0 -0
- /package/lib/{express → server}/middlewares/requireAuthUser.js +0 -0
- /package/lib/{express → server}/middlewares/requireRefreshUser.d.ts +0 -0
- /package/lib/{express → server}/middlewares/requireRefreshUser.js +0 -0
- /package/lib/{express → server}/statusCodes.d.ts +0 -0
- /package/lib/{express → server}/statusCodes.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [4.1.0](https://github.com/kevinand11/equipped/compare/v4.0.2-alpha.3...v4.1.0) (2023-03-07)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* access db name from mongoose ([febdee0](https://github.com/kevinand11/equipped/commit/febdee0264fe0f7d2de02fcd08a380a8c93df68c))
|
|
11
|
+
* add fanout option for event subscribers ([4f0c060](https://github.com/kevinand11/equipped/commit/4f0c060aa2d99fd6128499d49e1f163d1e93a721))
|
|
12
|
+
* add helmet and supertest ([71ddcad](https://github.com/kevinand11/equipped/commit/71ddcad4e2b191913a890e7480619f1df527fde1))
|
|
13
|
+
* add Id to mongo db ([55a8728](https://github.com/kevinand11/equipped/commit/55a872827a427a65a9be25ce464468935a4c5674))
|
|
14
|
+
* add kafka eventbus ([22f79d4](https://github.com/kevinand11/equipped/commit/22f79d48e48cc7c5695a43089f6a724f479ed81c))
|
|
15
|
+
* automatically start subscribers in Instance.startConnections ([96a07c9](https://github.com/kevinand11/equipped/commit/96a07c923a90b9203920ab490c4554098dfab5e8))
|
|
16
|
+
* enable defaults, getters and virtuals on lean docs ([69f9d2b](https://github.com/kevinand11/equipped/commit/69f9d2b5f26072e91d411cc1dd5e676264a6a586))
|
|
17
|
+
* enable lean documents for query ([ce04a8a](https://github.com/kevinand11/equipped/commit/ce04a8a326025916a32ce017634328c37c09a7e0))
|
|
18
|
+
* enable pre images for all collections ([710457d](https://github.com/kevinand11/equipped/commit/710457d1132cd380a0890b191f98fece4473729f))
|
|
19
|
+
* hydrate cs docs with getters and virtuals ([c93809a](https://github.com/kevinand11/equipped/commit/c93809ab8f2f4597fb310c68dc8d95b9f901aedd))
|
|
20
|
+
* new changestream api ([923660b](https://github.com/kevinand11/equipped/commit/923660b11c1ab6f799c030b37dc6ce06c3b90ebb))
|
|
21
|
+
* server request ip ([371dac1](https://github.com/kevinand11/equipped/commit/371dac18ef729c88da0e8885e1e63e581e8b979b))
|
|
22
|
+
* socket emitters fanout ([65a36db](https://github.com/kevinand11/equipped/commit/65a36db9671205a30fe8aabd3b1763714e94f886))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* hydrate _id from changes ([65e6539](https://github.com/kevinand11/equipped/commit/65e6539bfc9644421152af3ad5c0436a2b4ed3dc))
|
|
28
|
+
* loop over db connections ([eb3f548](https://github.com/kevinand11/equipped/commit/eb3f548f2e7a2f172cb4ead8ff655df0fc8f3b95))
|
|
29
|
+
* remove cache setInTransaction ([4f1b3c0](https://github.com/kevinand11/equipped/commit/4f1b3c0db37621162065c69fc24eab744675da27))
|
|
30
|
+
* setup debezium connection to mongo ([3d36283](https://github.com/kevinand11/equipped/commit/3d3628349910d8ba0633578b6578f09e682b8145))
|
|
31
|
+
|
|
32
|
+
### [4.0.2-alpha.3](https://github.com/kevinand11/equipped/compare/v4.0.2-alpha.2...v4.0.2-alpha.3) (2023-02-19)
|
|
33
|
+
|
|
34
|
+
### [4.0.2-alpha.2](https://github.com/kevinand11/equipped/compare/v4.0.2-alpha.1...v4.0.2-alpha.2) (2023-02-19)
|
|
35
|
+
|
|
36
|
+
### [4.0.2-alpha.1](https://github.com/kevinand11/equipped/compare/v4.0.2...v4.0.2-alpha.1) (2023-02-19)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Features
|
|
40
|
+
|
|
41
|
+
* make db change abstract ([e747c3f](https://github.com/kevinand11/equipped/commit/e747c3f2f74dc178521c3ee4d9a79efc8b160d32))
|
|
42
|
+
|
|
5
43
|
### [4.0.2](https://github.com/kevinand11/equipped/compare/v4.0.1...v4.0.2) (2023-02-16)
|
|
6
44
|
|
|
7
45
|
### [4.0.1](https://github.com/kevinand11/equipped/compare/v4.0.0-alpha-10...v4.0.1) (2023-02-16)
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Equipped
|
|
2
|
+
|
|
3
|
+
<br>
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/package/equipped).
|
|
8
|
+
Before installing, [download and install Node.js](https://nodejs.org/en/download/). Node.js 4.2.4 or higher is required.
|
|
9
|
+
If this is a brand new project, make sure to create a `package.json` first with the [`npm init` command](https://docs.npmjs.com/creating-a-package-json-file).
|
|
10
|
+
Installation is done using the [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
|
11
|
+
|
|
12
|
+
### Using npm:
|
|
13
|
+
npm install equipped
|
|
14
|
+
|
|
15
|
+
### Using yarn:
|
|
16
|
+
yarn add equipped
|
|
17
|
+
|
|
18
|
+
### Using CDN:
|
|
19
|
+
|
|
20
|
+
[Equipped jsDelivr CDN](https://www.jsdelivr.com/package/npm/equipped)
|
|
21
|
+
|
|
22
|
+
<br>
|
|
23
|
+
|
|
24
|
+
## Basic Usage
|
|
25
|
+
Before use, the package must be initialized in the entry point into your application, with the required settings.
|
|
26
|
+
```ts
|
|
27
|
+
import { Instance } from 'equipped'
|
|
28
|
+
|
|
29
|
+
Instance.initialize({
|
|
30
|
+
isDev: true, // Are you running in a dev environment
|
|
31
|
+
appId: 'testing', // An id to identify your application
|
|
32
|
+
mongoDbURI: 'mongodb://...', // A mongodb url if you want to use a database
|
|
33
|
+
redisURI: 'redis://localhost:6379', // A redis url if you want to use a redis cache. Confirm all other functionality you intend to use do not depend on the cache, even if you are not using a cache directly
|
|
34
|
+
...other settings
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
<br>
|
|
39
|
+
|
|
40
|
+
After the app has been initialized, the Instance class returns a singleton that provides access to most functionality provided by Equipped
|
|
41
|
+
```ts
|
|
42
|
+
import { Instance } from 'equipped'
|
|
43
|
+
|
|
44
|
+
const appInstance = Instance.get()
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
<br>
|
|
48
|
+
|
|
49
|
+
To start a server
|
|
50
|
+
```ts
|
|
51
|
+
import { makeController, StatusCodes } from 'equipped'
|
|
52
|
+
|
|
53
|
+
// Aggregate all your routes into an array. This can be defined in the file or imported from your controllers etc
|
|
54
|
+
appInstance.server.routes = [
|
|
55
|
+
{
|
|
56
|
+
path: '/',
|
|
57
|
+
method: 'get',
|
|
58
|
+
controllers: [makeController(async () => {
|
|
59
|
+
return {
|
|
60
|
+
result: 'Hello world',
|
|
61
|
+
status: StatusCodes.Ok
|
|
62
|
+
}
|
|
63
|
+
})]
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
await appInstance.server.start(8080)
|
|
68
|
+
```
|
package/lib/cache/cache.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare abstract class Cache {
|
|
2
|
-
abstract
|
|
2
|
+
abstract start(): Promise<void>;
|
|
3
|
+
abstract close(): Promise<void>;
|
|
3
4
|
abstract set(key: string, data: string, ttlInSecs: number): Promise<void>;
|
|
4
|
-
abstract setInTransaction(key: string, data: string, ttlInSecs: number): Promise<[string, string]>;
|
|
5
5
|
abstract get(key: string): Promise<string | null>;
|
|
6
6
|
abstract delete(key: string): Promise<void>;
|
|
7
7
|
}
|
|
@@ -2,10 +2,10 @@ import { createClient } from 'redis';
|
|
|
2
2
|
import { Cache } from '../cache';
|
|
3
3
|
export declare class RedisCache extends Cache {
|
|
4
4
|
client: ReturnType<typeof createClient>;
|
|
5
|
-
constructor(
|
|
6
|
-
|
|
5
|
+
constructor();
|
|
6
|
+
start(): Promise<void>;
|
|
7
|
+
close(): Promise<void>;
|
|
7
8
|
delete(key: string): Promise<void>;
|
|
8
9
|
get(key: string): Promise<string | null>;
|
|
9
10
|
set(key: string, data: string, ttlInSecs: number): Promise<void>;
|
|
10
|
-
setInTransaction(key: string, data: string, ttlInSecs: number): Promise<[string, string]>;
|
|
11
11
|
}
|
|
@@ -6,18 +6,19 @@ const exit_1 = require("../../exit");
|
|
|
6
6
|
const instance_1 = require("../../instance");
|
|
7
7
|
const cache_1 = require("../cache");
|
|
8
8
|
class RedisCache extends cache_1.Cache {
|
|
9
|
-
constructor(
|
|
9
|
+
constructor() {
|
|
10
10
|
super();
|
|
11
|
-
this.client = (0, redis_1.createClient)({ url:
|
|
11
|
+
this.client = (0, redis_1.createClient)({ url: instance_1.Instance.get().settings.redisURI });
|
|
12
12
|
this.client.on('error', async (error) => {
|
|
13
|
-
|
|
14
|
-
process.exit(1);
|
|
13
|
+
(0, exit_1.exit)(`Redis failed with error: ${error}`);
|
|
15
14
|
});
|
|
16
|
-
(0, exit_1.addWaitBeforeExit)(() => this.client.quit());
|
|
17
15
|
}
|
|
18
|
-
async
|
|
16
|
+
async start() {
|
|
19
17
|
await this.client.connect();
|
|
20
18
|
}
|
|
19
|
+
async close() {
|
|
20
|
+
this.client.quit();
|
|
21
|
+
}
|
|
21
22
|
async delete(key) {
|
|
22
23
|
await this.client.del(key);
|
|
23
24
|
}
|
|
@@ -30,11 +31,5 @@ class RedisCache extends cache_1.Cache {
|
|
|
30
31
|
else
|
|
31
32
|
this.client.set(key, data);
|
|
32
33
|
}
|
|
33
|
-
async setInTransaction(key, data, ttlInSecs) {
|
|
34
|
-
return await this.client.multi()
|
|
35
|
-
.get(key)
|
|
36
|
-
.setEx(key, ttlInSecs, data)
|
|
37
|
-
.exec();
|
|
38
|
-
}
|
|
39
34
|
}
|
|
40
35
|
exports.RedisCache = RedisCache;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BaseEntity } from '../structure';
|
|
2
|
+
import { DebeziumSetup } from './debezium';
|
|
3
|
+
import { QueryParams, QueryResults } from './query';
|
|
4
|
+
export declare abstract class Db {
|
|
5
|
+
#private;
|
|
6
|
+
abstract change<Model, Entity extends BaseEntity>(collection: any, callbacks: DbChangeCallbacks<Model, Entity>, mapper: (model: Model | null) => Entity | null): DbChange<Model, Entity>;
|
|
7
|
+
abstract query<Model>(collection: any, params: QueryParams): Promise<QueryResults<Model>>;
|
|
8
|
+
protected _addToDbChanges(dbChange: DbChange<any, any>): this;
|
|
9
|
+
startAllDbChanges(): Promise<void>;
|
|
10
|
+
abstract start(): Promise<void>;
|
|
11
|
+
abstract close(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare abstract class DbChange<Model, Entity extends BaseEntity> {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(callbacks: DbChangeCallbacks<Model, Entity>, mapper: (model: Model | null) => Entity | null);
|
|
16
|
+
abstract start(): Promise<void>;
|
|
17
|
+
get callbacks(): Readonly<DbChangeCallbacks<Model, Entity>>;
|
|
18
|
+
get mapper(): (model: Model | null) => Entity | null;
|
|
19
|
+
protected _setup(key: string, data: DebeziumSetup): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
type DeepPartial<T> = {
|
|
22
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
23
|
+
};
|
|
24
|
+
export type DbChangeCallbacks<Model, Entity> = {
|
|
25
|
+
created?: (data: {
|
|
26
|
+
before: null;
|
|
27
|
+
after: Entity;
|
|
28
|
+
}) => Promise<void>;
|
|
29
|
+
updated?: (data: {
|
|
30
|
+
before: Entity;
|
|
31
|
+
after: Entity;
|
|
32
|
+
changes: DeepPartial<Model>;
|
|
33
|
+
}) => Promise<void>;
|
|
34
|
+
deleted?: (data: {
|
|
35
|
+
before: Entity;
|
|
36
|
+
after: null;
|
|
37
|
+
}) => Promise<void>;
|
|
38
|
+
};
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _Db_dbChanges, _DbChange_callbacks, _DbChange_mapper;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.DbChange = exports.Db = void 0;
|
|
19
|
+
const axios_1 = __importDefault(require("axios"));
|
|
20
|
+
const exit_1 = require("../exit");
|
|
21
|
+
const instance_1 = require("../instance");
|
|
22
|
+
const debezium_1 = require("./debezium");
|
|
23
|
+
class Db {
|
|
24
|
+
constructor() {
|
|
25
|
+
_Db_dbChanges.set(this, []);
|
|
26
|
+
}
|
|
27
|
+
_addToDbChanges(dbChange) {
|
|
28
|
+
__classPrivateFieldGet(this, _Db_dbChanges, "f").push(dbChange);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
async startAllDbChanges() {
|
|
32
|
+
await Promise.all(__classPrivateFieldGet(this, _Db_dbChanges, "f").map((change) => change.start()));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.Db = Db;
|
|
36
|
+
_Db_dbChanges = new WeakMap();
|
|
37
|
+
class DbChange {
|
|
38
|
+
constructor(callbacks, mapper) {
|
|
39
|
+
_DbChange_callbacks.set(this, {});
|
|
40
|
+
_DbChange_mapper.set(this, void 0);
|
|
41
|
+
__classPrivateFieldSet(this, _DbChange_callbacks, callbacks, "f");
|
|
42
|
+
__classPrivateFieldSet(this, _DbChange_mapper, mapper, "f");
|
|
43
|
+
}
|
|
44
|
+
get callbacks() {
|
|
45
|
+
return Object.freeze(__classPrivateFieldGet(this, _DbChange_callbacks, "f"));
|
|
46
|
+
}
|
|
47
|
+
get mapper() {
|
|
48
|
+
return __classPrivateFieldGet(this, _DbChange_mapper, "f");
|
|
49
|
+
}
|
|
50
|
+
async _setup(key, data) {
|
|
51
|
+
data = { ...debezium_1.DefaultDebeziumSetup, ...data };
|
|
52
|
+
const topics = await axios_1.default.put(`/connectors/${key}/config`, data, { baseURL: instance_1.Instance.get().settings.debeziumUrl })
|
|
53
|
+
.then(async () => {
|
|
54
|
+
const res = await axios_1.default.get(`/connectors/${key}/topics`, { baseURL: instance_1.Instance.get().settings.debeziumUrl });
|
|
55
|
+
return res.data[key]?.topics ?? [];
|
|
56
|
+
})
|
|
57
|
+
.catch((err) => {
|
|
58
|
+
(0, exit_1.exit)(`Failed to setup debezium for ${key}: ${err.message}`);
|
|
59
|
+
return [];
|
|
60
|
+
});
|
|
61
|
+
return topics[0] === key;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.DbChange = DbChange;
|
|
65
|
+
_DbChange_callbacks = new WeakMap(), _DbChange_mapper = new WeakMap();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DebeziumSetup = Partial<{
|
|
2
|
+
'connector.class': string;
|
|
3
|
+
'topic.prefix': string;
|
|
4
|
+
'key.converter': string;
|
|
5
|
+
'key.converter.schemas.enable': string;
|
|
6
|
+
'value.converter': string;
|
|
7
|
+
'value.converter.schemas.enable': string;
|
|
8
|
+
}> & Record<string, string>;
|
|
9
|
+
export declare const TopicPrefix = "equipped";
|
|
10
|
+
export declare const DefaultDebeziumSetup: DebeziumSetup;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DefaultDebeziumSetup = exports.TopicPrefix = void 0;
|
|
4
|
+
exports.TopicPrefix = 'equipped';
|
|
5
|
+
exports.DefaultDebeziumSetup = {
|
|
6
|
+
'topic.prefix': exports.TopicPrefix,
|
|
7
|
+
'key.converter': 'org.apache.kafka.connect.json.JsonConverter',
|
|
8
|
+
'key.converter.schemas.enable': 'false',
|
|
9
|
+
'value.converter': 'org.apache.kafka.connect.json.JsonConverter',
|
|
10
|
+
'value.converter.schemas.enable': 'false'
|
|
11
|
+
};
|
|
@@ -13,12 +13,5 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
13
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.mongoose = void 0;
|
|
21
|
-
const mongoose_1 = __importDefault(require("mongoose"));
|
|
22
|
-
exports.mongoose = mongoose_1.default;
|
|
23
17
|
__exportStar(require("./query"), exports);
|
|
24
|
-
__exportStar(require("./changeStreams"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
import { BaseEntity } from '../../structure';
|
|
3
|
+
import { DbChange, DbChangeCallbacks } from '../_instance';
|
|
4
|
+
export declare class MongoDbChange<Model, Entity extends BaseEntity> extends DbChange<Model, Entity> {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(model: mongoose.Model<Model>, callbacks: DbChangeCallbacks<Model, Entity>, mapper: (model: Model | null) => Entity | null);
|
|
7
|
+
start(): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _MongoDbChange_started, _MongoDbChange_model;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.MongoDbChange = void 0;
|
|
19
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
20
|
+
const exit_1 = require("../../exit");
|
|
21
|
+
const instance_1 = require("../../instance");
|
|
22
|
+
const retry_1 = require("../../utils/retry");
|
|
23
|
+
const validations_1 = require("../../validations");
|
|
24
|
+
const debezium_1 = require("../debezium");
|
|
25
|
+
const _instance_1 = require("../_instance");
|
|
26
|
+
class MongoDbChange extends _instance_1.DbChange {
|
|
27
|
+
constructor(model, callbacks, mapper) {
|
|
28
|
+
super(callbacks, mapper);
|
|
29
|
+
_MongoDbChange_started.set(this, false);
|
|
30
|
+
_MongoDbChange_model.set(this, void 0);
|
|
31
|
+
__classPrivateFieldSet(this, _MongoDbChange_model, model, "f");
|
|
32
|
+
}
|
|
33
|
+
async start() {
|
|
34
|
+
if (__classPrivateFieldGet(this, _MongoDbChange_started, "f"))
|
|
35
|
+
return;
|
|
36
|
+
__classPrivateFieldSet(this, _MongoDbChange_started, true, "f");
|
|
37
|
+
const model = __classPrivateFieldGet(this, _MongoDbChange_model, "f");
|
|
38
|
+
const dbName = model.db.name;
|
|
39
|
+
const colName = model.collection.name;
|
|
40
|
+
const dbColName = `${dbName}.${colName}`;
|
|
41
|
+
const topic = `${debezium_1.TopicPrefix}.${dbColName}`;
|
|
42
|
+
(0, retry_1.retry)(async () => {
|
|
43
|
+
const { hosts, replicaSet, credentials } = model.collection.conn.getClient().options;
|
|
44
|
+
const started = await this._setup(topic, {
|
|
45
|
+
'connector.class': 'io.debezium.connector.mongodb.MongoDbConnector',
|
|
46
|
+
'capture.mode': 'change_streams_update_full_with_pre_image',
|
|
47
|
+
'mongodb.hosts': `${replicaSet}/` + hosts.map((h) => `${h.host}:${h.port}`).join(','),
|
|
48
|
+
...(credentials ? {
|
|
49
|
+
'mongodb.user': credentials.username,
|
|
50
|
+
'mongodb.pass': credentials.password,
|
|
51
|
+
'mongodb.auth-source': credentials.source
|
|
52
|
+
} : {}),
|
|
53
|
+
'collection.include.list': dbColName
|
|
54
|
+
});
|
|
55
|
+
const TestId = new mongoose_1.default.Types.ObjectId('__equipped__');
|
|
56
|
+
if (!started) {
|
|
57
|
+
await model.findByIdAndUpdate(TestId, { $set: { colName } }, { upsert: true });
|
|
58
|
+
await model.findByIdAndDelete(TestId);
|
|
59
|
+
throw new Error(`Wait a few minutes for db changes for ${colName} to initialize...`);
|
|
60
|
+
}
|
|
61
|
+
const hydrate = (data) => model.hydrate({
|
|
62
|
+
...data, _id: new mongoose_1.default.Types.ObjectId(data._id['$oid'])
|
|
63
|
+
}).toObject({ getters: true, virtuals: true });
|
|
64
|
+
if (started)
|
|
65
|
+
await instance_1.Instance.get().eventBus
|
|
66
|
+
.createSubscriber(topic, async (data) => {
|
|
67
|
+
const op = data.op;
|
|
68
|
+
let before = JSON.parse(data.before ?? 'null');
|
|
69
|
+
let after = JSON.parse(data.after ?? 'null');
|
|
70
|
+
if (before?.__id === TestId || after?.__id === TestId)
|
|
71
|
+
return;
|
|
72
|
+
if (before)
|
|
73
|
+
before = hydrate(before);
|
|
74
|
+
if (after)
|
|
75
|
+
after = hydrate(after);
|
|
76
|
+
if (op === 'c' && this.callbacks.created && after)
|
|
77
|
+
await this.callbacks.created({
|
|
78
|
+
before: null,
|
|
79
|
+
after: this.mapper(after)
|
|
80
|
+
});
|
|
81
|
+
else if (op === 'u' && this.callbacks.updated && before)
|
|
82
|
+
await this.callbacks.updated({
|
|
83
|
+
before: this.mapper(before),
|
|
84
|
+
after: this.mapper(after),
|
|
85
|
+
changes: validations_1.Validation.Differ.from(validations_1.Validation.Differ.diff(before, after))
|
|
86
|
+
});
|
|
87
|
+
else if (op === 'd' && this.callbacks.deleted && before)
|
|
88
|
+
await this.callbacks.deleted({
|
|
89
|
+
before: this.mapper(before),
|
|
90
|
+
after: null
|
|
91
|
+
});
|
|
92
|
+
})
|
|
93
|
+
.subscribe();
|
|
94
|
+
}, 10, 60000)
|
|
95
|
+
.catch((err) => (0, exit_1.exit)(err.message));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.MongoDbChange = MongoDbChange;
|
|
99
|
+
_MongoDbChange_started = new WeakMap(), _MongoDbChange_model = new WeakMap();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
import { BaseEntity } from '../../structure';
|
|
3
|
+
import { QueryParams, QueryResults } from '../query';
|
|
4
|
+
import { Db, DbChangeCallbacks } from '../_instance';
|
|
5
|
+
import { MongoDbChange } from './changes';
|
|
6
|
+
export declare class MongoDb extends Db {
|
|
7
|
+
#private;
|
|
8
|
+
get Schema(): typeof mongoose.Schema;
|
|
9
|
+
get Id(): mongoose.Types.ObjectId;
|
|
10
|
+
use(dbName?: string): mongoose.Connection;
|
|
11
|
+
change<Model, Entity extends BaseEntity>(model: mongoose.Model<Model>, callbacks: DbChangeCallbacks<Model, Entity>, mapper: (model: Model | null) => Entity | null): MongoDbChange<Model, Entity>;
|
|
12
|
+
query<Model>(model: mongoose.Model<Model>, params: QueryParams): Promise<QueryResults<Model>>;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _MongoDb_instances, _MongoDb_started, _MongoDb_connections_get;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.MongoDb = void 0;
|
|
19
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
20
|
+
const mongoose_lean_defaults_1 = __importDefault(require("mongoose-lean-defaults"));
|
|
21
|
+
const mongoose_lean_getters_1 = __importDefault(require("mongoose-lean-getters"));
|
|
22
|
+
const mongoose_lean_virtuals_1 = __importDefault(require("mongoose-lean-virtuals"));
|
|
23
|
+
const instance_1 = require("../../instance");
|
|
24
|
+
const _instance_1 = require("../_instance");
|
|
25
|
+
const changes_1 = require("./changes");
|
|
26
|
+
const query_1 = require("./query");
|
|
27
|
+
class MongoDb extends _instance_1.Db {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
_MongoDb_instances.add(this);
|
|
31
|
+
_MongoDb_started.set(this, false);
|
|
32
|
+
}
|
|
33
|
+
get Schema() {
|
|
34
|
+
return mongoose_1.default.Schema;
|
|
35
|
+
}
|
|
36
|
+
get Id() {
|
|
37
|
+
return new mongoose_1.default.Types.ObjectId();
|
|
38
|
+
}
|
|
39
|
+
use(dbName = 'default') {
|
|
40
|
+
const conn = dbName === 'default' ? mongoose_1.default.connection : mongoose_1.default.connection.useDb(dbName, { useCache: true });
|
|
41
|
+
conn.plugin(mongoose_lean_defaults_1.default).plugin(mongoose_lean_virtuals_1.default).plugin(mongoose_lean_getters_1.default);
|
|
42
|
+
return conn;
|
|
43
|
+
}
|
|
44
|
+
change(model, callbacks, mapper) {
|
|
45
|
+
const change = new changes_1.MongoDbChange(model, callbacks, mapper);
|
|
46
|
+
this._addToDbChanges(change);
|
|
47
|
+
return change;
|
|
48
|
+
}
|
|
49
|
+
async query(model, params) {
|
|
50
|
+
return await (0, query_1.parseMongodbQueryParams)(model, params);
|
|
51
|
+
}
|
|
52
|
+
async start() {
|
|
53
|
+
if (__classPrivateFieldGet(this, _MongoDb_started, "f"))
|
|
54
|
+
return;
|
|
55
|
+
__classPrivateFieldSet(this, _MongoDb_started, true, "f");
|
|
56
|
+
mongoose_1.default.set('strictQuery', true);
|
|
57
|
+
await mongoose_1.default.connect(instance_1.Instance.get().settings.mongoDbURI);
|
|
58
|
+
await Promise.all([mongoose_1.default.connection, ...__classPrivateFieldGet(this, _MongoDb_instances, "a", _MongoDb_connections_get)].map((conn) => {
|
|
59
|
+
return Object.values(conn.models)
|
|
60
|
+
.map(async (model) => {
|
|
61
|
+
await conn.db.command({ collMod: model.collection.name, changeStreamPreAndPostImages: { enabled: true } });
|
|
62
|
+
});
|
|
63
|
+
}).flat());
|
|
64
|
+
}
|
|
65
|
+
async close() {
|
|
66
|
+
await Promise.all(__classPrivateFieldGet(this, _MongoDb_instances, "a", _MongoDb_connections_get).map(async (conn) => conn.close()));
|
|
67
|
+
await mongoose_1.default.disconnect();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.MongoDb = MongoDb;
|
|
71
|
+
_MongoDb_started = new WeakMap(), _MongoDb_instances = new WeakSet(), _MongoDb_connections_get = function _MongoDb_connections_get() {
|
|
72
|
+
return mongoose_1.default.connection.otherDbs ?? [];
|
|
73
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
import { QueryParams, QueryResults } from '../query';
|
|
3
|
+
export declare const parseMongodbQueryParams: <Model>(model: mongoose.Model<Model, {}, {}, {}, mongoose.IfAny<Model, any, mongoose.Document<unknown, {}, Model> & Omit<mongoose.Require_id<Model>, never>>, any>, params: QueryParams) => Promise<QueryResults<Model>>;
|
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const instance_1 = require("
|
|
5
|
-
|
|
6
|
-
(
|
|
7
|
-
QueryKeys["and"] = "and";
|
|
8
|
-
QueryKeys["or"] = "or";
|
|
9
|
-
})(QueryKeys = exports.QueryKeys || (exports.QueryKeys = {}));
|
|
10
|
-
var Conditions;
|
|
11
|
-
(function (Conditions) {
|
|
12
|
-
Conditions["lt"] = "lt";
|
|
13
|
-
Conditions["lte"] = "lte";
|
|
14
|
-
Conditions["gt"] = "gt";
|
|
15
|
-
Conditions["gte"] = "gte";
|
|
16
|
-
Conditions["eq"] = "eq";
|
|
17
|
-
Conditions["ne"] = "ne";
|
|
18
|
-
Conditions["in"] = "in";
|
|
19
|
-
Conditions["nin"] = "nin";
|
|
20
|
-
Conditions["exists"] = "exists";
|
|
21
|
-
})(Conditions = exports.Conditions || (exports.Conditions = {}));
|
|
22
|
-
const parseQueryParams = async (collection, params) => {
|
|
3
|
+
exports.parseMongodbQueryParams = void 0;
|
|
4
|
+
const instance_1 = require("../../instance");
|
|
5
|
+
const query_1 = require("../query");
|
|
6
|
+
const parseMongodbQueryParams = async (model, params) => {
|
|
23
7
|
const query = [];
|
|
24
|
-
const whereType = Object.values(QueryKeys).indexOf(params.whereType) !== -1 ? params.whereType : QueryKeys.and;
|
|
25
|
-
const authType = Object.values(QueryKeys).indexOf(params.authType) !== -1 ? params.authType : QueryKeys.and;
|
|
8
|
+
const whereType = Object.values(query_1.QueryKeys).indexOf(params.whereType) !== -1 ? params.whereType : query_1.QueryKeys.and;
|
|
9
|
+
const authType = Object.values(query_1.QueryKeys).indexOf(params.authType) !== -1 ? params.authType : query_1.QueryKeys.and;
|
|
26
10
|
const where = buildWhereQuery(params.where ?? [], whereType);
|
|
27
11
|
if (where)
|
|
28
12
|
query.push(where);
|
|
@@ -46,8 +30,8 @@ const parseQueryParams = async (collection, params) => {
|
|
|
46
30
|
const limit = Number(params.limit) <= settings.paginationDefaultLimit ? Number(params.limit) : settings.paginationDefaultLimit;
|
|
47
31
|
let page = Number.isNaN(Number(params.page)) ? 0 : Number(params.page);
|
|
48
32
|
page = page < 1 ? 1 : page;
|
|
49
|
-
const total = await
|
|
50
|
-
let builtQuery =
|
|
33
|
+
const total = await model.countDocuments(totalClause);
|
|
34
|
+
let builtQuery = model.find(totalClause).lean({ virtuals: true, getters: true, defaults: true });
|
|
51
35
|
if (sort.length)
|
|
52
36
|
builtQuery = builtQuery.sort(Object.fromEntries(sort));
|
|
53
37
|
if (!all && limit) {
|
|
@@ -55,7 +39,7 @@ const parseQueryParams = async (collection, params) => {
|
|
|
55
39
|
if (page)
|
|
56
40
|
builtQuery = builtQuery.skip((page - 1) * limit);
|
|
57
41
|
}
|
|
58
|
-
const results = await builtQuery
|
|
42
|
+
const results = await builtQuery;
|
|
59
43
|
const start = 1;
|
|
60
44
|
const last = Math.ceil(total / limit) || 1;
|
|
61
45
|
const next = page >= last ? null : page + 1;
|
|
@@ -67,18 +51,18 @@ const parseQueryParams = async (collection, params) => {
|
|
|
67
51
|
docs: {
|
|
68
52
|
limit, total, count: results.length
|
|
69
53
|
},
|
|
70
|
-
results: results
|
|
54
|
+
results: results
|
|
71
55
|
};
|
|
72
56
|
};
|
|
73
|
-
exports.
|
|
74
|
-
const buildWhereQuery = (params, key = QueryKeys.and) => {
|
|
57
|
+
exports.parseMongodbQueryParams = parseMongodbQueryParams;
|
|
58
|
+
const buildWhereQuery = (params, key = query_1.QueryKeys.and) => {
|
|
75
59
|
const where = params.map((param) => {
|
|
76
|
-
if (Object.values(QueryKeys).includes(param.condition))
|
|
60
|
+
if (Object.values(query_1.QueryKeys).includes(param.condition))
|
|
77
61
|
return buildWhereQuery(param.value, param.condition);
|
|
78
62
|
const { field } = param;
|
|
79
63
|
const checkedField = field === 'id' ? '_id' : (field ?? '');
|
|
80
64
|
const checkedValue = param.value === undefined ? '' : param.value;
|
|
81
|
-
const checkedCondition = Object.keys(Conditions).indexOf(param.condition) > -1 ? param.condition : Conditions.eq;
|
|
65
|
+
const checkedCondition = Object.keys(query_1.Conditions).indexOf(param.condition) > -1 ? param.condition : query_1.Conditions.eq;
|
|
82
66
|
return ({
|
|
83
67
|
field: checkedField,
|
|
84
68
|
value: checkedValue,
|