@ciscode/database-kit 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/CHANGELOG.md +206 -0
- package/LICENSE +21 -0
- package/README.md +446 -0
- package/dist/adapters/mongo.adapter.d.ts +44 -0
- package/dist/adapters/mongo.adapter.d.ts.map +1 -0
- package/dist/adapters/mongo.adapter.js +146 -0
- package/dist/adapters/mongo.adapter.js.map +1 -0
- package/dist/adapters/postgres.adapter.d.ts +49 -0
- package/dist/adapters/postgres.adapter.d.ts.map +1 -0
- package/dist/adapters/postgres.adapter.js +229 -0
- package/dist/adapters/postgres.adapter.js.map +1 -0
- package/dist/config/database.config.d.ts +55 -0
- package/dist/config/database.config.d.ts.map +1 -0
- package/dist/config/database.config.js +122 -0
- package/dist/config/database.config.js.map +1 -0
- package/dist/config/database.constants.d.ts +41 -0
- package/dist/config/database.constants.d.ts.map +1 -0
- package/dist/config/database.constants.js +45 -0
- package/dist/config/database.constants.js.map +1 -0
- package/dist/contracts/database.contracts.d.ts +191 -0
- package/dist/contracts/database.contracts.d.ts.map +1 -0
- package/dist/contracts/database.contracts.js +21 -0
- package/dist/contracts/database.contracts.js.map +1 -0
- package/dist/database-kit.module.d.ts +71 -0
- package/dist/database-kit.module.d.ts.map +1 -0
- package/dist/database-kit.module.js +158 -0
- package/dist/database-kit.module.js.map +1 -0
- package/dist/filters/database-exception.filter.d.ts +51 -0
- package/dist/filters/database-exception.filter.d.ts.map +1 -0
- package/dist/filters/database-exception.filter.js +236 -0
- package/dist/filters/database-exception.filter.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/database.decorators.d.ts +31 -0
- package/dist/middleware/database.decorators.d.ts.map +1 -0
- package/dist/middleware/database.decorators.js +39 -0
- package/dist/middleware/database.decorators.js.map +1 -0
- package/dist/services/database.service.d.ts +99 -0
- package/dist/services/database.service.d.ts.map +1 -0
- package/dist/services/database.service.js +205 -0
- package/dist/services/database.service.js.map +1 -0
- package/dist/services/logger.service.d.ts +63 -0
- package/dist/services/logger.service.d.ts.map +1 -0
- package/dist/services/logger.service.js +93 -0
- package/dist/services/logger.service.js.map +1 -0
- package/dist/utils/pagination.utils.d.ts +57 -0
- package/dist/utils/pagination.utils.d.ts.map +1 -0
- package/dist/utils/pagination.utils.js +113 -0
- package/dist/utils/pagination.utils.js.map +1 -0
- package/dist/utils/validation.utils.d.ts +60 -0
- package/dist/utils/validation.utils.d.ts.map +1 -0
- package/dist/utils/validation.utils.js +117 -0
- package/dist/utils/validation.utils.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/adapters/mongo.adapter.ts
|
|
3
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
+
};
|
|
9
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
var MongoAdapter_1;
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.MongoAdapter = void 0;
|
|
18
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
19
|
+
const common_1 = require("@nestjs/common");
|
|
20
|
+
/**
|
|
21
|
+
* MongoDB adapter for DatabaseKit.
|
|
22
|
+
* Handles MongoDB connection and repository creation via Mongoose.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const adapter = new MongoAdapter({ type: 'mongo', connectionString: 'mongodb://...' });
|
|
27
|
+
* await adapter.connect();
|
|
28
|
+
* const repo = adapter.createRepository({ model: UserModel });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
let MongoAdapter = MongoAdapter_1 = class MongoAdapter {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.logger = new common_1.Logger(MongoAdapter_1.name);
|
|
34
|
+
this.config = config;
|
|
35
|
+
mongoose_1.default.set('strictQuery', false);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Establishes connection to MongoDB.
|
|
39
|
+
* Connection is lazy-loaded and cached for reuse.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Additional Mongoose connection options
|
|
42
|
+
* @returns Promise resolving to mongoose instance
|
|
43
|
+
*/
|
|
44
|
+
async connect(options = {}) {
|
|
45
|
+
if (!this.connectionPromise) {
|
|
46
|
+
this.logger.log('Connecting to MongoDB...');
|
|
47
|
+
this.connectionPromise = mongoose_1.default.connect(this.config.connectionString, {
|
|
48
|
+
maxPoolSize: 10,
|
|
49
|
+
serverSelectionTimeoutMS: 5000,
|
|
50
|
+
...options,
|
|
51
|
+
});
|
|
52
|
+
mongoose_1.default.connection.on('connected', () => {
|
|
53
|
+
this.logger.log('Successfully connected to MongoDB');
|
|
54
|
+
});
|
|
55
|
+
mongoose_1.default.connection.on('error', (err) => {
|
|
56
|
+
this.logger.error('MongoDB connection error', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
57
|
+
});
|
|
58
|
+
mongoose_1.default.connection.on('disconnected', () => {
|
|
59
|
+
this.logger.warn('MongoDB disconnected');
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return this.connectionPromise;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Gracefully disconnects from MongoDB.
|
|
66
|
+
*/
|
|
67
|
+
async disconnect() {
|
|
68
|
+
await mongoose_1.default.disconnect();
|
|
69
|
+
this.connectionPromise = undefined;
|
|
70
|
+
this.logger.log('Disconnected from MongoDB');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Checks if connected to MongoDB.
|
|
74
|
+
*/
|
|
75
|
+
isConnected() {
|
|
76
|
+
return mongoose_1.default.connection.readyState === 1;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Creates a repository for a Mongoose model.
|
|
80
|
+
* The repository provides a standardized CRUD interface.
|
|
81
|
+
*
|
|
82
|
+
* @param opts - Options containing the Mongoose model
|
|
83
|
+
* @returns Repository instance with CRUD methods
|
|
84
|
+
*/
|
|
85
|
+
createRepository(opts) {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
const model = opts.model;
|
|
88
|
+
const shapePage = (data, page, limit, total) => {
|
|
89
|
+
const pages = Math.max(1, Math.ceil((total || 0) / (limit || 1)));
|
|
90
|
+
return { data, page, limit, total, pages };
|
|
91
|
+
};
|
|
92
|
+
const repo = {
|
|
93
|
+
async create(data) {
|
|
94
|
+
var _a, _b, _c;
|
|
95
|
+
const doc = await model.create(data);
|
|
96
|
+
return (_c = (_b = (_a = doc).toObject) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : doc;
|
|
97
|
+
},
|
|
98
|
+
async findById(id) {
|
|
99
|
+
const doc = await model.findById(id).lean().exec();
|
|
100
|
+
return doc;
|
|
101
|
+
},
|
|
102
|
+
async findAll(filter = {}) {
|
|
103
|
+
const docs = await model.find(filter).lean().exec();
|
|
104
|
+
return docs;
|
|
105
|
+
},
|
|
106
|
+
async findPage(options = {}) {
|
|
107
|
+
const { filter = {}, page = 1, limit = 10, sort } = options;
|
|
108
|
+
const skip = Math.max(0, (page - 1) * limit);
|
|
109
|
+
let query = model.find(filter).skip(skip).limit(limit);
|
|
110
|
+
if (sort) {
|
|
111
|
+
query = query.sort(sort);
|
|
112
|
+
}
|
|
113
|
+
const [data, total] = await Promise.all([
|
|
114
|
+
query.lean().exec(),
|
|
115
|
+
model.countDocuments(filter).exec(),
|
|
116
|
+
]);
|
|
117
|
+
return shapePage(data, page, limit, total);
|
|
118
|
+
},
|
|
119
|
+
async updateById(id, update) {
|
|
120
|
+
const doc = await model
|
|
121
|
+
.findByIdAndUpdate(id, update, { new: true })
|
|
122
|
+
.lean()
|
|
123
|
+
.exec();
|
|
124
|
+
return doc;
|
|
125
|
+
},
|
|
126
|
+
async deleteById(id) {
|
|
127
|
+
const res = await model.findByIdAndDelete(id).lean().exec();
|
|
128
|
+
return !!res;
|
|
129
|
+
},
|
|
130
|
+
async count(filter = {}) {
|
|
131
|
+
return model.countDocuments(filter).exec();
|
|
132
|
+
},
|
|
133
|
+
async exists(filter = {}) {
|
|
134
|
+
const res = await model.exists(filter);
|
|
135
|
+
return !!res;
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
return repo;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
exports.MongoAdapter = MongoAdapter;
|
|
142
|
+
exports.MongoAdapter = MongoAdapter = MongoAdapter_1 = __decorate([
|
|
143
|
+
(0, common_1.Injectable)(),
|
|
144
|
+
__metadata("design:paramtypes", [Object])
|
|
145
|
+
], MongoAdapter);
|
|
146
|
+
//# sourceMappingURL=mongo.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo.adapter.js","sourceRoot":"","sources":["../../src/adapters/mongo.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Knex } from 'knex';
|
|
2
|
+
import { PostgresDatabaseConfig, PostgresEntityConfig, Repository } from '../contracts/database.contracts';
|
|
3
|
+
/**
|
|
4
|
+
* PostgreSQL adapter for DatabaseKit.
|
|
5
|
+
* Handles PostgreSQL connection and repository creation via Knex.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const adapter = new PostgresAdapter({ type: 'postgres', connectionString: 'postgresql://...' });
|
|
10
|
+
* adapter.connect();
|
|
11
|
+
* const repo = adapter.createRepository({ table: 'users', primaryKey: 'id' });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class PostgresAdapter {
|
|
15
|
+
private readonly logger;
|
|
16
|
+
private readonly config;
|
|
17
|
+
private knexInstance?;
|
|
18
|
+
constructor(config: PostgresDatabaseConfig);
|
|
19
|
+
/**
|
|
20
|
+
* Creates and returns the Knex instance for PostgreSQL.
|
|
21
|
+
* Connection is lazy-loaded and cached for reuse.
|
|
22
|
+
*
|
|
23
|
+
* @param overrides - Additional Knex configuration overrides
|
|
24
|
+
* @returns Knex instance
|
|
25
|
+
*/
|
|
26
|
+
connect(overrides?: Knex.Config): Knex;
|
|
27
|
+
/**
|
|
28
|
+
* Gracefully destroys the connection pool.
|
|
29
|
+
*/
|
|
30
|
+
disconnect(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the Knex instance.
|
|
33
|
+
* Throws if not connected.
|
|
34
|
+
*/
|
|
35
|
+
getKnex(): Knex;
|
|
36
|
+
/**
|
|
37
|
+
* Checks if connected to PostgreSQL.
|
|
38
|
+
*/
|
|
39
|
+
isConnected(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Creates a repository for a PostgreSQL table.
|
|
42
|
+
* The repository provides a standardized CRUD interface.
|
|
43
|
+
*
|
|
44
|
+
* @param cfg - Configuration for the entity/table
|
|
45
|
+
* @returns Repository instance with CRUD methods
|
|
46
|
+
*/
|
|
47
|
+
createRepository<T = unknown>(cfg: PostgresEntityConfig): Repository<T>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=postgres.adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/postgres.adapter.ts"],"names":[],"mappings":"AAEA,OAAa,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EACH,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EAGb,MAAM,iCAAiC,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,qBACa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,YAAY,CAAC,CAAO;gBAEhB,MAAM,EAAE,sBAAsB;IAI1C;;;;;;OAMG;IACH,OAAO,CAAC,SAAS,GAAE,IAAI,CAAC,MAAW,GAAG,IAAI;IAiB1C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAOf;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,oBAAoB,GAAG,UAAU,CAAC,CAAC,CAAC;CA0J1E"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/adapters/postgres.adapter.ts
|
|
3
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
+
};
|
|
9
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
10
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
var PostgresAdapter_1;
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.PostgresAdapter = void 0;
|
|
18
|
+
const knex_1 = __importDefault(require("knex"));
|
|
19
|
+
const common_1 = require("@nestjs/common");
|
|
20
|
+
/**
|
|
21
|
+
* PostgreSQL adapter for DatabaseKit.
|
|
22
|
+
* Handles PostgreSQL connection and repository creation via Knex.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const adapter = new PostgresAdapter({ type: 'postgres', connectionString: 'postgresql://...' });
|
|
27
|
+
* adapter.connect();
|
|
28
|
+
* const repo = adapter.createRepository({ table: 'users', primaryKey: 'id' });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
let PostgresAdapter = PostgresAdapter_1 = class PostgresAdapter {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.logger = new common_1.Logger(PostgresAdapter_1.name);
|
|
34
|
+
this.config = config;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates and returns the Knex instance for PostgreSQL.
|
|
38
|
+
* Connection is lazy-loaded and cached for reuse.
|
|
39
|
+
*
|
|
40
|
+
* @param overrides - Additional Knex configuration overrides
|
|
41
|
+
* @returns Knex instance
|
|
42
|
+
*/
|
|
43
|
+
connect(overrides = {}) {
|
|
44
|
+
if (!this.knexInstance) {
|
|
45
|
+
this.logger.log('Creating PostgreSQL connection pool...');
|
|
46
|
+
this.knexInstance = (0, knex_1.default)({
|
|
47
|
+
client: 'pg',
|
|
48
|
+
connection: this.config.connectionString,
|
|
49
|
+
pool: { min: 0, max: 10 },
|
|
50
|
+
...overrides,
|
|
51
|
+
});
|
|
52
|
+
this.logger.log('PostgreSQL connection pool created');
|
|
53
|
+
}
|
|
54
|
+
return this.knexInstance;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Gracefully destroys the connection pool.
|
|
58
|
+
*/
|
|
59
|
+
async disconnect() {
|
|
60
|
+
if (this.knexInstance) {
|
|
61
|
+
await this.knexInstance.destroy();
|
|
62
|
+
this.knexInstance = undefined;
|
|
63
|
+
this.logger.log('PostgreSQL connection pool destroyed');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns the Knex instance.
|
|
68
|
+
* Throws if not connected.
|
|
69
|
+
*/
|
|
70
|
+
getKnex() {
|
|
71
|
+
if (!this.knexInstance) {
|
|
72
|
+
throw new Error('PostgreSQL not connected. Call connect() first.');
|
|
73
|
+
}
|
|
74
|
+
return this.knexInstance;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Checks if connected to PostgreSQL.
|
|
78
|
+
*/
|
|
79
|
+
isConnected() {
|
|
80
|
+
return !!this.knexInstance;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Creates a repository for a PostgreSQL table.
|
|
84
|
+
* The repository provides a standardized CRUD interface.
|
|
85
|
+
*
|
|
86
|
+
* @param cfg - Configuration for the entity/table
|
|
87
|
+
* @returns Repository instance with CRUD methods
|
|
88
|
+
*/
|
|
89
|
+
createRepository(cfg) {
|
|
90
|
+
const kx = this.getKnex();
|
|
91
|
+
const table = cfg.table;
|
|
92
|
+
const pk = cfg.primaryKey || 'id';
|
|
93
|
+
const allowed = cfg.columns || [];
|
|
94
|
+
const baseFilter = cfg.defaultFilter || {};
|
|
95
|
+
const assertFieldAllowed = (field) => {
|
|
96
|
+
if (allowed.length && !allowed.includes(field)) {
|
|
97
|
+
throw new Error(`Field "${field}" is not allowed for table "${table}". Add it to columns[] in config.`);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const applyFilter = (qb, filter) => {
|
|
101
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
102
|
+
assertFieldAllowed(key);
|
|
103
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
104
|
+
const ops = value;
|
|
105
|
+
if (ops.eq !== undefined)
|
|
106
|
+
qb.where(key, ops.eq);
|
|
107
|
+
if (ops.ne !== undefined)
|
|
108
|
+
qb.whereNot(key, ops.ne);
|
|
109
|
+
if (ops.gt !== undefined)
|
|
110
|
+
qb.where(key, '>', ops.gt);
|
|
111
|
+
if (ops.gte !== undefined)
|
|
112
|
+
qb.where(key, '>=', ops.gte);
|
|
113
|
+
if (ops.lt !== undefined)
|
|
114
|
+
qb.where(key, '<', ops.lt);
|
|
115
|
+
if (ops.lte !== undefined)
|
|
116
|
+
qb.where(key, '<=', ops.lte);
|
|
117
|
+
if (ops.in)
|
|
118
|
+
qb.whereIn(key, ops.in);
|
|
119
|
+
if (ops.nin)
|
|
120
|
+
qb.whereNotIn(key, ops.nin);
|
|
121
|
+
if (ops.like)
|
|
122
|
+
qb.whereILike(key, `${ops.like}`);
|
|
123
|
+
if (ops.isNull === true)
|
|
124
|
+
qb.whereNull(key);
|
|
125
|
+
if (ops.isNotNull === true)
|
|
126
|
+
qb.whereNotNull(key);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
qb.where(key, value);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
const applySort = (qb, sort) => {
|
|
134
|
+
if (!sort)
|
|
135
|
+
return;
|
|
136
|
+
if (typeof sort === 'string') {
|
|
137
|
+
const parts = sort.split(',');
|
|
138
|
+
for (const p of parts) {
|
|
139
|
+
const dir = p.startsWith('-') ? 'desc' : 'asc';
|
|
140
|
+
const col = p.replace(/^[-+]/, '');
|
|
141
|
+
assertFieldAllowed(col);
|
|
142
|
+
qb.orderBy(col, dir);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
Object.entries(sort).forEach(([col, dir]) => {
|
|
147
|
+
assertFieldAllowed(col);
|
|
148
|
+
const direction = dir === -1 || String(dir).toLowerCase() === 'desc' ? 'desc' : 'asc';
|
|
149
|
+
qb.orderBy(col, direction);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const shapePage = (data, page, limit, total) => {
|
|
154
|
+
const pages = Math.max(1, Math.ceil((total || 0) / (limit || 1)));
|
|
155
|
+
return { data, page, limit, total, pages };
|
|
156
|
+
};
|
|
157
|
+
const repo = {
|
|
158
|
+
async create(data) {
|
|
159
|
+
const [row] = await kx(table).insert(data).returning('*');
|
|
160
|
+
return row;
|
|
161
|
+
},
|
|
162
|
+
async findById(id) {
|
|
163
|
+
const row = await kx(table)
|
|
164
|
+
.select('*')
|
|
165
|
+
.where({ [pk]: id, ...baseFilter })
|
|
166
|
+
.first();
|
|
167
|
+
return row || null;
|
|
168
|
+
},
|
|
169
|
+
async findAll(filter = {}) {
|
|
170
|
+
const mergedFilter = { ...baseFilter, ...filter };
|
|
171
|
+
const qb = kx(table).select('*');
|
|
172
|
+
applyFilter(qb, mergedFilter);
|
|
173
|
+
const rows = await qb;
|
|
174
|
+
return rows;
|
|
175
|
+
},
|
|
176
|
+
async findPage(options = {}) {
|
|
177
|
+
var _a;
|
|
178
|
+
const { filter = {}, page = 1, limit = 10, sort } = options;
|
|
179
|
+
const mergedFilter = { ...baseFilter, ...filter };
|
|
180
|
+
const offset = Math.max(0, (page - 1) * limit);
|
|
181
|
+
const qb = kx(table).select('*');
|
|
182
|
+
applyFilter(qb, mergedFilter);
|
|
183
|
+
applySort(qb, sort);
|
|
184
|
+
const data = (await qb.clone().limit(limit).offset(offset));
|
|
185
|
+
const countRow = await kx(table)
|
|
186
|
+
.count({ count: '*' })
|
|
187
|
+
.modify((q) => applyFilter(q, mergedFilter));
|
|
188
|
+
const total = Number(((_a = countRow[0]) === null || _a === void 0 ? void 0 : _a.count) || 0);
|
|
189
|
+
return shapePage(data, page, limit, total);
|
|
190
|
+
},
|
|
191
|
+
async updateById(id, update) {
|
|
192
|
+
const [row] = await kx(table)
|
|
193
|
+
.where({ [pk]: id })
|
|
194
|
+
.update(update)
|
|
195
|
+
.returning('*');
|
|
196
|
+
return row || null;
|
|
197
|
+
},
|
|
198
|
+
async deleteById(id) {
|
|
199
|
+
const [row] = await kx(table)
|
|
200
|
+
.where({ [pk]: id })
|
|
201
|
+
.delete()
|
|
202
|
+
.returning('*');
|
|
203
|
+
return !!row;
|
|
204
|
+
},
|
|
205
|
+
async count(filter = {}) {
|
|
206
|
+
const mergedFilter = { ...baseFilter, ...filter };
|
|
207
|
+
const [{ count }] = await kx(table)
|
|
208
|
+
.count({ count: '*' })
|
|
209
|
+
.modify((q) => applyFilter(q, mergedFilter));
|
|
210
|
+
return Number(count || 0);
|
|
211
|
+
},
|
|
212
|
+
async exists(filter = {}) {
|
|
213
|
+
const mergedFilter = { ...baseFilter, ...filter };
|
|
214
|
+
const row = await kx(table)
|
|
215
|
+
.select([pk])
|
|
216
|
+
.modify((q) => applyFilter(q, mergedFilter))
|
|
217
|
+
.first();
|
|
218
|
+
return !!row;
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
return repo;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
exports.PostgresAdapter = PostgresAdapter;
|
|
225
|
+
exports.PostgresAdapter = PostgresAdapter = PostgresAdapter_1 = __decorate([
|
|
226
|
+
(0, common_1.Injectable)(),
|
|
227
|
+
__metadata("design:paramtypes", [Object])
|
|
228
|
+
], PostgresAdapter);
|
|
229
|
+
//# sourceMappingURL=postgres.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.adapter.js","sourceRoot":"","sources":["../../src/adapters/postgres.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { DatabaseConfig } from '../contracts/database.contracts';
|
|
2
|
+
/**
|
|
3
|
+
* Helper class for environment-driven database configuration.
|
|
4
|
+
* Implements fail-fast pattern with clear error messages.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DatabaseConfigHelper {
|
|
7
|
+
/**
|
|
8
|
+
* Gets an environment variable value.
|
|
9
|
+
* Throws an error if the variable is not set.
|
|
10
|
+
*
|
|
11
|
+
* @param name - Environment variable name
|
|
12
|
+
* @returns The environment variable value
|
|
13
|
+
* @throws Error if the variable is not configured
|
|
14
|
+
*/
|
|
15
|
+
static getEnv(name: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Gets an optional environment variable value.
|
|
18
|
+
*
|
|
19
|
+
* @param name - Environment variable name
|
|
20
|
+
* @param defaultValue - Default value if not set
|
|
21
|
+
* @returns The environment variable value or default
|
|
22
|
+
*/
|
|
23
|
+
static getEnvOrDefault(name: string, defaultValue: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Gets an environment variable as a number.
|
|
26
|
+
*
|
|
27
|
+
* @param name - Environment variable name
|
|
28
|
+
* @param defaultValue - Default value if not set
|
|
29
|
+
* @returns The parsed number value
|
|
30
|
+
*/
|
|
31
|
+
static getEnvAsNumber(name: string, defaultValue: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Builds a database configuration from environment variables.
|
|
34
|
+
*
|
|
35
|
+
* @returns DatabaseConfig object
|
|
36
|
+
* @throws Error if required environment variables are missing
|
|
37
|
+
*/
|
|
38
|
+
static fromEnv(): DatabaseConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Validates a database configuration.
|
|
41
|
+
*
|
|
42
|
+
* @param config - The configuration to validate
|
|
43
|
+
* @throws Error if configuration is invalid
|
|
44
|
+
*/
|
|
45
|
+
static validate(config: DatabaseConfig): void;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the pool size from environment or default.
|
|
48
|
+
*/
|
|
49
|
+
static getPoolSize(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Gets the connection timeout from environment or default.
|
|
52
|
+
*/
|
|
53
|
+
static getConnectionTimeout(): number;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=database.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.config.d.ts","sourceRoot":"","sources":["../../src/config/database.config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAgB,MAAM,iCAAiC,CAAC;AAG/E;;;GAGG;AACH,qBAAa,oBAAoB;IAC7B;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAWnC;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAIlE;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAajE;;;;;OAKG;IACH,MAAM,CAAC,OAAO,IAAI,cAAc;IAsBhC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAsC7C;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACH,MAAM,CAAC,oBAAoB,IAAI,MAAM;CAMxC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/config/database.config.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.DatabaseConfigHelper = void 0;
|
|
5
|
+
const database_constants_1 = require("./database.constants");
|
|
6
|
+
/**
|
|
7
|
+
* Helper class for environment-driven database configuration.
|
|
8
|
+
* Implements fail-fast pattern with clear error messages.
|
|
9
|
+
*/
|
|
10
|
+
class DatabaseConfigHelper {
|
|
11
|
+
/**
|
|
12
|
+
* Gets an environment variable value.
|
|
13
|
+
* Throws an error if the variable is not set.
|
|
14
|
+
*
|
|
15
|
+
* @param name - Environment variable name
|
|
16
|
+
* @returns The environment variable value
|
|
17
|
+
* @throws Error if the variable is not configured
|
|
18
|
+
*/
|
|
19
|
+
static getEnv(name) {
|
|
20
|
+
const value = process.env[name];
|
|
21
|
+
if (!value) {
|
|
22
|
+
throw new Error(`Environment variable ${name} is not configured. ` +
|
|
23
|
+
`Please set it in your .env file or environment.`);
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets an optional environment variable value.
|
|
29
|
+
*
|
|
30
|
+
* @param name - Environment variable name
|
|
31
|
+
* @param defaultValue - Default value if not set
|
|
32
|
+
* @returns The environment variable value or default
|
|
33
|
+
*/
|
|
34
|
+
static getEnvOrDefault(name, defaultValue) {
|
|
35
|
+
return process.env[name] || defaultValue;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets an environment variable as a number.
|
|
39
|
+
*
|
|
40
|
+
* @param name - Environment variable name
|
|
41
|
+
* @param defaultValue - Default value if not set
|
|
42
|
+
* @returns The parsed number value
|
|
43
|
+
*/
|
|
44
|
+
static getEnvAsNumber(name, defaultValue) {
|
|
45
|
+
const value = process.env[name];
|
|
46
|
+
if (!value)
|
|
47
|
+
return defaultValue;
|
|
48
|
+
const parsed = parseInt(value, 10);
|
|
49
|
+
if (isNaN(parsed)) {
|
|
50
|
+
throw new Error(`Environment variable ${name} must be a valid number. Got: ${value}`);
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Builds a database configuration from environment variables.
|
|
56
|
+
*
|
|
57
|
+
* @returns DatabaseConfig object
|
|
58
|
+
* @throws Error if required environment variables are missing
|
|
59
|
+
*/
|
|
60
|
+
static fromEnv() {
|
|
61
|
+
const type = this.getEnv(database_constants_1.ENV_KEYS.DATABASE_TYPE);
|
|
62
|
+
if (type !== 'mongo' && type !== 'postgres') {
|
|
63
|
+
throw new Error(`Invalid DATABASE_TYPE: "${String(type)}". Must be "mongo" or "postgres".`);
|
|
64
|
+
}
|
|
65
|
+
if (type === 'mongo') {
|
|
66
|
+
return {
|
|
67
|
+
type: 'mongo',
|
|
68
|
+
connectionString: this.getEnv(database_constants_1.ENV_KEYS.MONGO_URI),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
type: 'postgres',
|
|
73
|
+
connectionString: this.getEnv(database_constants_1.ENV_KEYS.POSTGRES_URI),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validates a database configuration.
|
|
78
|
+
*
|
|
79
|
+
* @param config - The configuration to validate
|
|
80
|
+
* @throws Error if configuration is invalid
|
|
81
|
+
*/
|
|
82
|
+
static validate(config) {
|
|
83
|
+
// Cast to unknown for runtime validation since config may come from external sources
|
|
84
|
+
const rawConfig = config;
|
|
85
|
+
if (!rawConfig.type) {
|
|
86
|
+
throw new Error('Database configuration must include a type');
|
|
87
|
+
}
|
|
88
|
+
if (rawConfig.type !== 'mongo' && rawConfig.type !== 'postgres') {
|
|
89
|
+
throw new Error(`Invalid database type: "${rawConfig.type}". Must be "mongo" or "postgres".`);
|
|
90
|
+
}
|
|
91
|
+
if (!rawConfig.connectionString) {
|
|
92
|
+
throw new Error('Database configuration must include a connectionString');
|
|
93
|
+
}
|
|
94
|
+
// Basic connection string validation
|
|
95
|
+
if (config.type === 'mongo') {
|
|
96
|
+
if (!config.connectionString.startsWith('mongodb://') &&
|
|
97
|
+
!config.connectionString.startsWith('mongodb+srv://')) {
|
|
98
|
+
throw new Error('MongoDB connection string must start with "mongodb://" or "mongodb+srv://"');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (config.type === 'postgres') {
|
|
102
|
+
if (!config.connectionString.startsWith('postgresql://') &&
|
|
103
|
+
!config.connectionString.startsWith('postgres://')) {
|
|
104
|
+
throw new Error('PostgreSQL connection string must start with "postgresql://" or "postgres://"');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Gets the pool size from environment or default.
|
|
110
|
+
*/
|
|
111
|
+
static getPoolSize() {
|
|
112
|
+
return this.getEnvAsNumber(database_constants_1.ENV_KEYS.POOL_SIZE, database_constants_1.DEFAULTS.POOL_SIZE);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Gets the connection timeout from environment or default.
|
|
116
|
+
*/
|
|
117
|
+
static getConnectionTimeout() {
|
|
118
|
+
return this.getEnvAsNumber(database_constants_1.ENV_KEYS.CONNECTION_TIMEOUT, database_constants_1.DEFAULTS.CONNECTION_TIMEOUT);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.DatabaseConfigHelper = DatabaseConfigHelper;
|
|
122
|
+
//# sourceMappingURL=database.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.config.js","sourceRoot":"","sources":["../../src/config/database.config.ts"],"names":[],"mappings":"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"}
|