@onivoro/server-typeorm-postgres 0.1.32 → 22.0.1
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/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/lib/classes/redshift-repository.class.d.ts +26 -0
- package/dist/cjs/lib/classes/redshift-repository.class.js +131 -0
- package/dist/cjs/lib/classes/type-orm-repository.class.d.ts +33 -1
- package/dist/cjs/lib/classes/type-orm-repository.class.js +108 -1
- package/dist/cjs/lib/decorators/nullable-table-column.decorator.d.ts +1 -1
- package/dist/cjs/lib/decorators/primary-table-column.decorator.d.ts +1 -1
- package/dist/cjs/lib/decorators/table-column.decorator.d.ts +1 -1
- package/dist/cjs/lib/decorators/table.decorator.d.ts +1 -1
- package/dist/cjs/lib/functions/data-source-config-factory.function.js +1 -2
- package/dist/cjs/lib/functions/generate-date-query.function.js +1 -2
- package/dist/cjs/lib/functions/get-api-type-from-column.function.js +1 -2
- package/dist/cjs/lib/functions/get-paging-key.function.js +1 -2
- package/dist/cjs/lib/functions/get-skip.function.js +1 -2
- package/dist/cjs/lib/functions/remove-falsey-keys.function.js +1 -2
- package/dist/cjs/lib/types/table-meta.type.d.ts +9 -0
- package/dist/cjs/lib/types/table-meta.type.js +2 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/lib/classes/redshift-repository.class.d.ts +26 -0
- package/dist/esm/lib/classes/redshift-repository.class.js +131 -0
- package/dist/esm/lib/classes/type-orm-repository.class.d.ts +33 -1
- package/dist/esm/lib/classes/type-orm-repository.class.js +108 -1
- package/dist/esm/lib/decorators/nullable-table-column.decorator.d.ts +1 -1
- package/dist/esm/lib/decorators/primary-table-column.decorator.d.ts +1 -1
- package/dist/esm/lib/decorators/table-column.decorator.d.ts +1 -1
- package/dist/esm/lib/decorators/table.decorator.d.ts +1 -1
- package/dist/esm/lib/functions/data-source-config-factory.function.js +1 -2
- package/dist/esm/lib/functions/generate-date-query.function.js +1 -2
- package/dist/esm/lib/functions/get-api-type-from-column.function.js +1 -2
- package/dist/esm/lib/functions/get-paging-key.function.js +1 -2
- package/dist/esm/lib/functions/get-skip.function.js +1 -2
- package/dist/esm/lib/functions/remove-falsey-keys.function.js +1 -2
- package/dist/esm/lib/types/table-meta.type.d.ts +9 -0
- package/dist/esm/lib/types/table-meta.type.js +2 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/classes/redshift-repository.class.d.ts +26 -0
- package/dist/types/lib/classes/type-orm-repository.class.d.ts +33 -1
- package/dist/types/lib/decorators/nullable-table-column.decorator.d.ts +1 -1
- package/dist/types/lib/decorators/primary-table-column.decorator.d.ts +1 -1
- package/dist/types/lib/decorators/table-column.decorator.d.ts +1 -1
- package/dist/types/lib/decorators/table.decorator.d.ts +1 -1
- package/dist/types/lib/types/table-meta.type.d.ts +9 -0
- package/package.json +7 -7
package/dist/cjs/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './lib/classes/columns-migration-base.class';
|
|
|
3
3
|
export * from './lib/classes/drop-column-migration-base.class';
|
|
4
4
|
export * from './lib/classes/drop-table-migration-base.class';
|
|
5
5
|
export * from './lib/classes/index-migration-base.class';
|
|
6
|
+
export * from './lib/classes/redshift-repository.class';
|
|
6
7
|
export * from './lib/classes/sql-writer.class';
|
|
7
8
|
export * from './lib/classes/table-migration-base.class';
|
|
8
9
|
export * from './lib/classes/type-orm-paging-repository.class';
|
|
@@ -23,4 +24,5 @@ export * from './lib/types/data-source-options.interface';
|
|
|
23
24
|
export * from './lib/types/entity-provider.interface';
|
|
24
25
|
export * from './lib/types/page-params.interface';
|
|
25
26
|
export * from './lib/types/paged-data.interface';
|
|
27
|
+
export * from './lib/types/table-meta.type';
|
|
26
28
|
export * from './lib/server-typeorm-postgres.module';
|
package/dist/cjs/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./lib/classes/columns-migration-base.class"), exports);
|
|
|
19
19
|
__exportStar(require("./lib/classes/drop-column-migration-base.class"), exports);
|
|
20
20
|
__exportStar(require("./lib/classes/drop-table-migration-base.class"), exports);
|
|
21
21
|
__exportStar(require("./lib/classes/index-migration-base.class"), exports);
|
|
22
|
+
__exportStar(require("./lib/classes/redshift-repository.class"), exports);
|
|
22
23
|
__exportStar(require("./lib/classes/sql-writer.class"), exports);
|
|
23
24
|
__exportStar(require("./lib/classes/table-migration-base.class"), exports);
|
|
24
25
|
__exportStar(require("./lib/classes/type-orm-paging-repository.class"), exports);
|
|
@@ -39,4 +40,5 @@ __exportStar(require("./lib/types/data-source-options.interface"), exports);
|
|
|
39
40
|
__exportStar(require("./lib/types/entity-provider.interface"), exports);
|
|
40
41
|
__exportStar(require("./lib/types/page-params.interface"), exports);
|
|
41
42
|
__exportStar(require("./lib/types/paged-data.interface"), exports);
|
|
43
|
+
__exportStar(require("./lib/types/table-meta.type"), exports);
|
|
42
44
|
__exportStar(require("./lib/server-typeorm-postgres.module"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
|
+
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
|
+
import { TypeOrmRepository } from './type-orm-repository.class';
|
|
4
|
+
export declare class RedshiftRepository<TEntity> extends TypeOrmRepository<TEntity> {
|
|
5
|
+
entityType: any;
|
|
6
|
+
entityManager: EntityManager;
|
|
7
|
+
constructor(entityType: any, entityManager: EntityManager);
|
|
8
|
+
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
9
|
+
getOne(options: FindOneOptions<TEntity>): Promise<TEntity>;
|
|
10
|
+
delete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
11
|
+
patch(where: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
12
|
+
postOne(entity: Partial<TEntity>): Promise<TEntity>;
|
|
13
|
+
postMany(entities: Partial<TEntity>[]): Promise<TEntity[]>;
|
|
14
|
+
put(options: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
15
|
+
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
16
|
+
getManyAndCount(options: FindManyOptions<TEntity>): Promise<[TEntity[], number]>;
|
|
17
|
+
softDelete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
18
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
19
|
+
insertQuery: string;
|
|
20
|
+
values: any[];
|
|
21
|
+
};
|
|
22
|
+
private mapPlaceholderExpression;
|
|
23
|
+
postOneWithoutReturn(entity: Partial<TEntity>): Promise<void>;
|
|
24
|
+
postManyWithoutReturn(entities: Partial<TEntity>[]): Promise<void>;
|
|
25
|
+
private throwNotImplemented;
|
|
26
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RedshiftRepository = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
const type_orm_repository_class_1 = require("./type-orm-repository.class");
|
|
16
|
+
let RedshiftRepository = class RedshiftRepository extends type_orm_repository_class_1.TypeOrmRepository {
|
|
17
|
+
entityType;
|
|
18
|
+
entityManager;
|
|
19
|
+
constructor(entityType, entityManager) {
|
|
20
|
+
super(entityType, entityManager);
|
|
21
|
+
this.entityType = entityType;
|
|
22
|
+
this.entityManager = entityManager;
|
|
23
|
+
}
|
|
24
|
+
async getMany(options) {
|
|
25
|
+
const { query, queryParams } = this.buildSelectStatement(options);
|
|
26
|
+
return await this.queryAndMap(query, queryParams);
|
|
27
|
+
}
|
|
28
|
+
async getOne(options) {
|
|
29
|
+
const results = await this.getMany(options);
|
|
30
|
+
if (results.length > 1) {
|
|
31
|
+
throw new Error(`RedshiftRepository.getOne expected one result but found ${results.length} results`);
|
|
32
|
+
}
|
|
33
|
+
return results[0];
|
|
34
|
+
}
|
|
35
|
+
async delete(where) {
|
|
36
|
+
const { query, queryParams } = this.buildDeleteStatement(where);
|
|
37
|
+
await this.query(query, queryParams);
|
|
38
|
+
}
|
|
39
|
+
async patch(where, body) {
|
|
40
|
+
const queryParams = [];
|
|
41
|
+
let whereClause = '';
|
|
42
|
+
Object.entries(where).forEach(([propertyPath, value], index) => {
|
|
43
|
+
const key = this.columns[propertyPath].databasePath;
|
|
44
|
+
if (index === 0) {
|
|
45
|
+
whereClause += ` WHERE ${key} = ${this.mapPlaceholderExpression(0, index, propertyPath)}`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
whereClause += ` AND ${key} = ${this.mapPlaceholderExpression(0, index, propertyPath)}`;
|
|
49
|
+
}
|
|
50
|
+
queryParams.push(value);
|
|
51
|
+
});
|
|
52
|
+
const setParams = [];
|
|
53
|
+
let setExpressions = [];
|
|
54
|
+
const length = queryParams?.length;
|
|
55
|
+
Object.entries(body).forEach(([key, value], index) => {
|
|
56
|
+
setExpressions.push(`${this.columns[key].databasePath} = ${this.mapPlaceholderExpression(length, index, key)}`);
|
|
57
|
+
setParams.push(value);
|
|
58
|
+
});
|
|
59
|
+
let query = `UPDATE "${this.table}" SET ${setExpressions.join(', ')} ${whereClause}`;
|
|
60
|
+
await this.query(query, [...queryParams, ...setParams]);
|
|
61
|
+
}
|
|
62
|
+
async postOne(entity) {
|
|
63
|
+
await this.postOneWithoutReturn(entity);
|
|
64
|
+
return await this.getOne({ where: entity });
|
|
65
|
+
}
|
|
66
|
+
async postMany(entities) {
|
|
67
|
+
const { insertQuery, values } = this.buildInsertManyQuery(entities);
|
|
68
|
+
await this.query(insertQuery, values);
|
|
69
|
+
const { selectQuery, values: selectValues } = this.buildSelectManyQuery(entities);
|
|
70
|
+
return await this.queryAndMap(selectQuery, selectValues);
|
|
71
|
+
}
|
|
72
|
+
async put(options, body) {
|
|
73
|
+
this.throwNotImplemented('put');
|
|
74
|
+
}
|
|
75
|
+
forTransaction(entityManager) {
|
|
76
|
+
this.throwNotImplemented('forTransaction');
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
async getManyAndCount(options) {
|
|
80
|
+
this.throwNotImplemented('getManyAndCount');
|
|
81
|
+
return [[], 0];
|
|
82
|
+
}
|
|
83
|
+
async softDelete(where) {
|
|
84
|
+
await this.patch(where, { deletedAt: new Date().toISOString() });
|
|
85
|
+
}
|
|
86
|
+
buildInsertManyQuery(entities) {
|
|
87
|
+
const keyMap = {};
|
|
88
|
+
entities.forEach(entity => {
|
|
89
|
+
Object.keys(entity)
|
|
90
|
+
.forEach(key => {
|
|
91
|
+
keyMap[key] = true;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
const columnNames = Object.keys(keyMap).map(key => this.columns[key].databasePath).join(', ');
|
|
95
|
+
const valuesExpressions = [];
|
|
96
|
+
const values = [];
|
|
97
|
+
entities.forEach(entity => {
|
|
98
|
+
const length = values.length;
|
|
99
|
+
Object.keys(keyMap).forEach(key => {
|
|
100
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
101
|
+
});
|
|
102
|
+
const paramPlaceholders = Object.keys(keyMap).map((_, index) => this.mapPlaceholderExpression(length, index, _)).join(', ');
|
|
103
|
+
valuesExpressions.push(`(${paramPlaceholders})`);
|
|
104
|
+
});
|
|
105
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES ${valuesExpressions.join(', ')}`;
|
|
106
|
+
return { insertQuery, values };
|
|
107
|
+
}
|
|
108
|
+
mapPlaceholderExpression(length, index, column) {
|
|
109
|
+
const exp = `$${length + index + 1}`;
|
|
110
|
+
const meta = this.columns[column];
|
|
111
|
+
return meta.type === 'jsonb' ? `JSON_PARSE('${exp}')` : exp;
|
|
112
|
+
}
|
|
113
|
+
async postOneWithoutReturn(entity) {
|
|
114
|
+
// PERFORM AN INSERT BUT NOT THE RETRIEVAL QUERY FOR PERFORMANCE
|
|
115
|
+
const { insertQuery, values } = this.buildInsertQuery(entity);
|
|
116
|
+
await this.query(insertQuery, values);
|
|
117
|
+
}
|
|
118
|
+
async postManyWithoutReturn(entities) {
|
|
119
|
+
// TODO: PERFORM AN INSERT BUT NOT THE RETRIEVAL QUERY FOR PERFORMANCE
|
|
120
|
+
// TODO: THIS IS ACTUALLY NEEDED TO HELP WITH LARGE DATASETS
|
|
121
|
+
this.throwNotImplemented('postManyWithoutReturn');
|
|
122
|
+
}
|
|
123
|
+
throwNotImplemented(feature) {
|
|
124
|
+
throw new common_1.NotImplementedException(`RedshiftRepository of type "${this.entityType?.name}" has no implementation for "${feature}"`);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
exports.RedshiftRepository = RedshiftRepository;
|
|
128
|
+
exports.RedshiftRepository = RedshiftRepository = __decorate([
|
|
129
|
+
(0, common_1.Injectable)(),
|
|
130
|
+
__metadata("design:paramtypes", [Object, typeorm_1.EntityManager])
|
|
131
|
+
], RedshiftRepository);
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
2
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
3
|
import { IEntityProvider } from '../types/entity-provider.interface';
|
|
4
|
+
import { TKeysOf } from '@onivoro/isomorphic-common';
|
|
5
|
+
import { TTableMeta } from '../types/table-meta.type';
|
|
4
6
|
export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEntity, FindOneOptions<TEntity>, FindManyOptions<TEntity>, FindOptionsWhere<TEntity>, QueryDeepPartialEntity<TEntity>> {
|
|
5
|
-
|
|
7
|
+
entityType: any;
|
|
6
8
|
entityManager: EntityManager;
|
|
9
|
+
protected columns: TKeysOf<TEntity, TTableMeta>;
|
|
10
|
+
protected table: string;
|
|
11
|
+
debug: boolean;
|
|
7
12
|
constructor(entityType: any, entityManager: EntityManager);
|
|
8
13
|
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
9
14
|
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
@@ -18,4 +23,31 @@ export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEnti
|
|
|
18
23
|
get repo(): import("typeorm").Repository<import("typeorm").ObjectLiteral>;
|
|
19
24
|
protected insertAndReturn(entityToInsert: TEntity): Promise<TEntity>;
|
|
20
25
|
protected insertAndReturnMany(entitiesToInsert: TEntity[]): Promise<TEntity[]>;
|
|
26
|
+
protected buildSelectStatement(options: FindManyOptions<TEntity>): {
|
|
27
|
+
query: string;
|
|
28
|
+
queryParams: any[];
|
|
29
|
+
};
|
|
30
|
+
protected buildDeleteStatement(where: FindManyOptions<TEntity>): {
|
|
31
|
+
query: string;
|
|
32
|
+
queryParams: any[];
|
|
33
|
+
};
|
|
34
|
+
protected buildWhereExpression(where?: FindOptionsWhere<TEntity>): {
|
|
35
|
+
queryParams: any[];
|
|
36
|
+
whereClause: string;
|
|
37
|
+
};
|
|
38
|
+
protected buildInsertQuery(entity: Partial<TEntity>): {
|
|
39
|
+
insertQuery: string;
|
|
40
|
+
values: any[];
|
|
41
|
+
};
|
|
42
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
43
|
+
insertQuery: string;
|
|
44
|
+
values: any[];
|
|
45
|
+
};
|
|
46
|
+
protected buildSelectManyQuery(entities: Partial<TEntity>[]): {
|
|
47
|
+
selectQuery: string;
|
|
48
|
+
values: any[];
|
|
49
|
+
};
|
|
50
|
+
map(raw: any): TEntity;
|
|
51
|
+
query(query: string, parameters: any[]): Promise<any[]>;
|
|
52
|
+
queryAndMap(query: string, parameters: any[]): Promise<TEntity[]>;
|
|
21
53
|
}
|
|
@@ -4,12 +4,21 @@ exports.TypeOrmRepository = void 0;
|
|
|
4
4
|
class TypeOrmRepository {
|
|
5
5
|
entityType;
|
|
6
6
|
entityManager;
|
|
7
|
+
columns = {};
|
|
8
|
+
table;
|
|
9
|
+
debug = false;
|
|
7
10
|
constructor(entityType, entityManager) {
|
|
8
11
|
this.entityType = entityType;
|
|
9
12
|
this.entityManager = entityManager;
|
|
13
|
+
const { tableName } = this.repo.metadata;
|
|
14
|
+
this.table = tableName;
|
|
15
|
+
this.repo.metadata.columns.forEach((_) => {
|
|
16
|
+
const { databasePath, propertyPath, type, isPrimary } = _;
|
|
17
|
+
this.columns[propertyPath] = { databasePath, type, propertyPath, isPrimary, default: _.default };
|
|
18
|
+
});
|
|
10
19
|
}
|
|
11
20
|
forTransaction(entityManager) {
|
|
12
|
-
return
|
|
21
|
+
return new this.constructor(this.entityType, entityManager);
|
|
13
22
|
}
|
|
14
23
|
async getMany(options) {
|
|
15
24
|
return await this.repo.find(options);
|
|
@@ -58,5 +67,103 @@ class TypeOrmRepository {
|
|
|
58
67
|
const insertedEntity = insertionResult.generatedMaps;
|
|
59
68
|
return insertedEntity;
|
|
60
69
|
}
|
|
70
|
+
buildSelectStatement(options) {
|
|
71
|
+
const { whereClause, queryParams } = this.buildWhereExpression(options.where);
|
|
72
|
+
const query = `SELECT * FROM "${this.table}"${whereClause};`;
|
|
73
|
+
return { query, queryParams };
|
|
74
|
+
}
|
|
75
|
+
buildDeleteStatement(where) {
|
|
76
|
+
const { whereClause, queryParams } = this.buildWhereExpression(where);
|
|
77
|
+
const query = `DELETE FROM "${this.table}"${whereClause};`;
|
|
78
|
+
return { query, queryParams };
|
|
79
|
+
}
|
|
80
|
+
buildWhereExpression(where) {
|
|
81
|
+
const queryParams = [];
|
|
82
|
+
let whereClause = '';
|
|
83
|
+
Object.entries(where || {}).forEach(([propertyPath, value], index) => {
|
|
84
|
+
const key = this.columns[propertyPath].databasePath;
|
|
85
|
+
if (index === 0) {
|
|
86
|
+
whereClause += ` WHERE ${key} = $${index + 1}`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
whereClause += ` AND ${key} = $${index + 1}`;
|
|
90
|
+
}
|
|
91
|
+
queryParams.push(value);
|
|
92
|
+
});
|
|
93
|
+
return { queryParams, whereClause };
|
|
94
|
+
}
|
|
95
|
+
buildInsertQuery(entity) {
|
|
96
|
+
const keys = Object.keys(entity);
|
|
97
|
+
const values = Object.values(entity);
|
|
98
|
+
const columnNames = keys.map(key => this.columns[key].databasePath).join(', ');
|
|
99
|
+
const paramPlaceholders = keys.map((_, index) => `$${index + 1}`).join(', ');
|
|
100
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES (${paramPlaceholders})`;
|
|
101
|
+
return { insertQuery, values };
|
|
102
|
+
}
|
|
103
|
+
buildInsertManyQuery(entities) {
|
|
104
|
+
const keyMap = {};
|
|
105
|
+
entities.forEach(entity => {
|
|
106
|
+
Object.keys(entity)
|
|
107
|
+
.forEach(key => {
|
|
108
|
+
keyMap[key] = true;
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
const columnNames = Object.keys(keyMap).map(key => this.columns[key].databasePath).join(', ');
|
|
112
|
+
const valuesExpressions = [];
|
|
113
|
+
const values = [];
|
|
114
|
+
entities.forEach(entity => {
|
|
115
|
+
const length = values.length;
|
|
116
|
+
Object.keys(keyMap).forEach(key => {
|
|
117
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
118
|
+
});
|
|
119
|
+
const paramPlaceholders = Object.keys(keyMap).map((_, index) => `$${length + index + 1}`).join(', ');
|
|
120
|
+
valuesExpressions.push(`(${paramPlaceholders})`);
|
|
121
|
+
});
|
|
122
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES ${valuesExpressions.join(', ')}`;
|
|
123
|
+
return { insertQuery, values };
|
|
124
|
+
}
|
|
125
|
+
buildSelectManyQuery(entities) {
|
|
126
|
+
const keyMap = {};
|
|
127
|
+
entities.forEach(entity => {
|
|
128
|
+
Object.keys(entity)
|
|
129
|
+
.forEach(key => {
|
|
130
|
+
keyMap[key] = true;
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
const selectExpressions = [];
|
|
134
|
+
const values = [];
|
|
135
|
+
entities.forEach(entity => {
|
|
136
|
+
const length = values.length;
|
|
137
|
+
Object.keys(keyMap).forEach(key => {
|
|
138
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
139
|
+
});
|
|
140
|
+
const whereExpression = Object.keys(keyMap).map((_, index) => `(${this.columns[_].databasePath} = $${length + index + 1})`).join(' AND ');
|
|
141
|
+
selectExpressions.push(`(select * from "${this.table}" where (${whereExpression}))`);
|
|
142
|
+
});
|
|
143
|
+
const selectQuery = selectExpressions.join(' UNION ');
|
|
144
|
+
return { selectQuery, values };
|
|
145
|
+
}
|
|
146
|
+
map(raw) {
|
|
147
|
+
const mapped = Object.values(this.columns)
|
|
148
|
+
.reduce((entity, { propertyPath, databasePath, type }) => {
|
|
149
|
+
entity[propertyPath] = raw[databasePath];
|
|
150
|
+
return entity;
|
|
151
|
+
}, {});
|
|
152
|
+
return mapped;
|
|
153
|
+
}
|
|
154
|
+
async query(query, parameters) {
|
|
155
|
+
if (this.debug) {
|
|
156
|
+
console.log({ table: this.table, query, parameters });
|
|
157
|
+
}
|
|
158
|
+
const result = await this.repo.query(query, parameters);
|
|
159
|
+
if (this.debug) {
|
|
160
|
+
console.log({ table: this.table, query, parameters, result });
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
async queryAndMap(query, parameters) {
|
|
165
|
+
const result = await this.query(query, parameters);
|
|
166
|
+
return result?.map((_) => this.map(_));
|
|
167
|
+
}
|
|
61
168
|
}
|
|
62
169
|
exports.TypeOrmRepository = TypeOrmRepository;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const NullableTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const NullableTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const TableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const TableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const Table: (EntityClass: {
|
|
2
2
|
name: string;
|
|
3
|
-
}) => <TFunction extends Function, Y>(target:
|
|
3
|
+
}) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dataSourceConfigFactory =
|
|
3
|
+
exports.dataSourceConfigFactory = dataSourceConfigFactory;
|
|
4
4
|
const typeorm_naming_strategies_1 = require("typeorm-naming-strategies");
|
|
5
5
|
function dataSourceConfigFactory(name, options, entities) {
|
|
6
6
|
const { ca, database, host, password, port, username, synchronize = false, logging = false } = options;
|
|
@@ -22,4 +22,3 @@ function dataSourceConfigFactory(name, options, entities) {
|
|
|
22
22
|
};
|
|
23
23
|
return config;
|
|
24
24
|
}
|
|
25
|
-
exports.dataSourceConfigFactory = dataSourceConfigFactory;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateDateQuery =
|
|
3
|
+
exports.generateDateQuery = generateDateQuery;
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
function generateDateQuery(minDueDate, maxDueDate) {
|
|
6
6
|
if (minDueDate && maxDueDate) {
|
|
@@ -14,4 +14,3 @@ function generateDateQuery(minDueDate, maxDueDate) {
|
|
|
14
14
|
}
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
|
-
exports.generateDateQuery = generateDateQuery;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getApiTypeFromColumn =
|
|
3
|
+
exports.getApiTypeFromColumn = getApiTypeFromColumn;
|
|
4
4
|
function getApiTypeFromColumn(columnType) {
|
|
5
5
|
if (!columnType) {
|
|
6
6
|
return 'string';
|
|
@@ -12,4 +12,3 @@ function getApiTypeFromColumn(columnType) {
|
|
|
12
12
|
return 'string';
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
exports.getApiTypeFromColumn = getApiTypeFromColumn;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPagingKey =
|
|
3
|
+
exports.getPagingKey = getPagingKey;
|
|
4
4
|
function getPagingKey(pageSize, skip, total) {
|
|
5
5
|
return pageSize * skip < total ? skip + 1 : undefined;
|
|
6
6
|
}
|
|
7
|
-
exports.getPagingKey = getPagingKey;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.removeFalseyKeys =
|
|
3
|
+
exports.removeFalseyKeys = removeFalseyKeys;
|
|
4
4
|
function removeFalseyKeys(obj) {
|
|
5
5
|
return Object.entries(obj)
|
|
6
6
|
.filter(([k, v]) => typeof v !== 'undefined')
|
|
@@ -9,4 +9,3 @@ function removeFalseyKeys(obj) {
|
|
|
9
9
|
return acc;
|
|
10
10
|
}, {});
|
|
11
11
|
}
|
|
12
|
-
exports.removeFalseyKeys = removeFalseyKeys;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColumnType } from "typeorm";
|
|
2
|
+
import { ColumnMetadata } from "typeorm/metadata/ColumnMetadata.js";
|
|
3
|
+
export type TTableMeta = {
|
|
4
|
+
databasePath: string;
|
|
5
|
+
type: ColumnType;
|
|
6
|
+
propertyPath: string;
|
|
7
|
+
isPrimary: boolean;
|
|
8
|
+
default: ColumnMetadata['default'];
|
|
9
|
+
};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './lib/classes/columns-migration-base.class';
|
|
|
3
3
|
export * from './lib/classes/drop-column-migration-base.class';
|
|
4
4
|
export * from './lib/classes/drop-table-migration-base.class';
|
|
5
5
|
export * from './lib/classes/index-migration-base.class';
|
|
6
|
+
export * from './lib/classes/redshift-repository.class';
|
|
6
7
|
export * from './lib/classes/sql-writer.class';
|
|
7
8
|
export * from './lib/classes/table-migration-base.class';
|
|
8
9
|
export * from './lib/classes/type-orm-paging-repository.class';
|
|
@@ -23,4 +24,5 @@ export * from './lib/types/data-source-options.interface';
|
|
|
23
24
|
export * from './lib/types/entity-provider.interface';
|
|
24
25
|
export * from './lib/types/page-params.interface';
|
|
25
26
|
export * from './lib/types/paged-data.interface';
|
|
27
|
+
export * from './lib/types/table-meta.type';
|
|
26
28
|
export * from './lib/server-typeorm-postgres.module';
|
package/dist/esm/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./lib/classes/columns-migration-base.class"), exports);
|
|
|
19
19
|
__exportStar(require("./lib/classes/drop-column-migration-base.class"), exports);
|
|
20
20
|
__exportStar(require("./lib/classes/drop-table-migration-base.class"), exports);
|
|
21
21
|
__exportStar(require("./lib/classes/index-migration-base.class"), exports);
|
|
22
|
+
__exportStar(require("./lib/classes/redshift-repository.class"), exports);
|
|
22
23
|
__exportStar(require("./lib/classes/sql-writer.class"), exports);
|
|
23
24
|
__exportStar(require("./lib/classes/table-migration-base.class"), exports);
|
|
24
25
|
__exportStar(require("./lib/classes/type-orm-paging-repository.class"), exports);
|
|
@@ -39,4 +40,5 @@ __exportStar(require("./lib/types/data-source-options.interface"), exports);
|
|
|
39
40
|
__exportStar(require("./lib/types/entity-provider.interface"), exports);
|
|
40
41
|
__exportStar(require("./lib/types/page-params.interface"), exports);
|
|
41
42
|
__exportStar(require("./lib/types/paged-data.interface"), exports);
|
|
43
|
+
__exportStar(require("./lib/types/table-meta.type"), exports);
|
|
42
44
|
__exportStar(require("./lib/server-typeorm-postgres.module"), exports);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
|
+
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
|
+
import { TypeOrmRepository } from './type-orm-repository.class';
|
|
4
|
+
export declare class RedshiftRepository<TEntity> extends TypeOrmRepository<TEntity> {
|
|
5
|
+
entityType: any;
|
|
6
|
+
entityManager: EntityManager;
|
|
7
|
+
constructor(entityType: any, entityManager: EntityManager);
|
|
8
|
+
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
9
|
+
getOne(options: FindOneOptions<TEntity>): Promise<TEntity>;
|
|
10
|
+
delete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
11
|
+
patch(where: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
12
|
+
postOne(entity: Partial<TEntity>): Promise<TEntity>;
|
|
13
|
+
postMany(entities: Partial<TEntity>[]): Promise<TEntity[]>;
|
|
14
|
+
put(options: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
15
|
+
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
16
|
+
getManyAndCount(options: FindManyOptions<TEntity>): Promise<[TEntity[], number]>;
|
|
17
|
+
softDelete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
18
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
19
|
+
insertQuery: string;
|
|
20
|
+
values: any[];
|
|
21
|
+
};
|
|
22
|
+
private mapPlaceholderExpression;
|
|
23
|
+
postOneWithoutReturn(entity: Partial<TEntity>): Promise<void>;
|
|
24
|
+
postManyWithoutReturn(entities: Partial<TEntity>[]): Promise<void>;
|
|
25
|
+
private throwNotImplemented;
|
|
26
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RedshiftRepository = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const typeorm_1 = require("typeorm");
|
|
15
|
+
const type_orm_repository_class_1 = require("./type-orm-repository.class");
|
|
16
|
+
let RedshiftRepository = class RedshiftRepository extends type_orm_repository_class_1.TypeOrmRepository {
|
|
17
|
+
entityType;
|
|
18
|
+
entityManager;
|
|
19
|
+
constructor(entityType, entityManager) {
|
|
20
|
+
super(entityType, entityManager);
|
|
21
|
+
this.entityType = entityType;
|
|
22
|
+
this.entityManager = entityManager;
|
|
23
|
+
}
|
|
24
|
+
async getMany(options) {
|
|
25
|
+
const { query, queryParams } = this.buildSelectStatement(options);
|
|
26
|
+
return await this.queryAndMap(query, queryParams);
|
|
27
|
+
}
|
|
28
|
+
async getOne(options) {
|
|
29
|
+
const results = await this.getMany(options);
|
|
30
|
+
if (results.length > 1) {
|
|
31
|
+
throw new Error(`RedshiftRepository.getOne expected one result but found ${results.length} results`);
|
|
32
|
+
}
|
|
33
|
+
return results[0];
|
|
34
|
+
}
|
|
35
|
+
async delete(where) {
|
|
36
|
+
const { query, queryParams } = this.buildDeleteStatement(where);
|
|
37
|
+
await this.query(query, queryParams);
|
|
38
|
+
}
|
|
39
|
+
async patch(where, body) {
|
|
40
|
+
const queryParams = [];
|
|
41
|
+
let whereClause = '';
|
|
42
|
+
Object.entries(where).forEach(([propertyPath, value], index) => {
|
|
43
|
+
const key = this.columns[propertyPath].databasePath;
|
|
44
|
+
if (index === 0) {
|
|
45
|
+
whereClause += ` WHERE ${key} = ${this.mapPlaceholderExpression(0, index, propertyPath)}`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
whereClause += ` AND ${key} = ${this.mapPlaceholderExpression(0, index, propertyPath)}`;
|
|
49
|
+
}
|
|
50
|
+
queryParams.push(value);
|
|
51
|
+
});
|
|
52
|
+
const setParams = [];
|
|
53
|
+
let setExpressions = [];
|
|
54
|
+
const length = queryParams?.length;
|
|
55
|
+
Object.entries(body).forEach(([key, value], index) => {
|
|
56
|
+
setExpressions.push(`${this.columns[key].databasePath} = ${this.mapPlaceholderExpression(length, index, key)}`);
|
|
57
|
+
setParams.push(value);
|
|
58
|
+
});
|
|
59
|
+
let query = `UPDATE "${this.table}" SET ${setExpressions.join(', ')} ${whereClause}`;
|
|
60
|
+
await this.query(query, [...queryParams, ...setParams]);
|
|
61
|
+
}
|
|
62
|
+
async postOne(entity) {
|
|
63
|
+
await this.postOneWithoutReturn(entity);
|
|
64
|
+
return await this.getOne({ where: entity });
|
|
65
|
+
}
|
|
66
|
+
async postMany(entities) {
|
|
67
|
+
const { insertQuery, values } = this.buildInsertManyQuery(entities);
|
|
68
|
+
await this.query(insertQuery, values);
|
|
69
|
+
const { selectQuery, values: selectValues } = this.buildSelectManyQuery(entities);
|
|
70
|
+
return await this.queryAndMap(selectQuery, selectValues);
|
|
71
|
+
}
|
|
72
|
+
async put(options, body) {
|
|
73
|
+
this.throwNotImplemented('put');
|
|
74
|
+
}
|
|
75
|
+
forTransaction(entityManager) {
|
|
76
|
+
this.throwNotImplemented('forTransaction');
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
async getManyAndCount(options) {
|
|
80
|
+
this.throwNotImplemented('getManyAndCount');
|
|
81
|
+
return [[], 0];
|
|
82
|
+
}
|
|
83
|
+
async softDelete(where) {
|
|
84
|
+
await this.patch(where, { deletedAt: new Date().toISOString() });
|
|
85
|
+
}
|
|
86
|
+
buildInsertManyQuery(entities) {
|
|
87
|
+
const keyMap = {};
|
|
88
|
+
entities.forEach(entity => {
|
|
89
|
+
Object.keys(entity)
|
|
90
|
+
.forEach(key => {
|
|
91
|
+
keyMap[key] = true;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
const columnNames = Object.keys(keyMap).map(key => this.columns[key].databasePath).join(', ');
|
|
95
|
+
const valuesExpressions = [];
|
|
96
|
+
const values = [];
|
|
97
|
+
entities.forEach(entity => {
|
|
98
|
+
const length = values.length;
|
|
99
|
+
Object.keys(keyMap).forEach(key => {
|
|
100
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
101
|
+
});
|
|
102
|
+
const paramPlaceholders = Object.keys(keyMap).map((_, index) => this.mapPlaceholderExpression(length, index, _)).join(', ');
|
|
103
|
+
valuesExpressions.push(`(${paramPlaceholders})`);
|
|
104
|
+
});
|
|
105
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES ${valuesExpressions.join(', ')}`;
|
|
106
|
+
return { insertQuery, values };
|
|
107
|
+
}
|
|
108
|
+
mapPlaceholderExpression(length, index, column) {
|
|
109
|
+
const exp = `$${length + index + 1}`;
|
|
110
|
+
const meta = this.columns[column];
|
|
111
|
+
return meta.type === 'jsonb' ? `JSON_PARSE('${exp}')` : exp;
|
|
112
|
+
}
|
|
113
|
+
async postOneWithoutReturn(entity) {
|
|
114
|
+
// PERFORM AN INSERT BUT NOT THE RETRIEVAL QUERY FOR PERFORMANCE
|
|
115
|
+
const { insertQuery, values } = this.buildInsertQuery(entity);
|
|
116
|
+
await this.query(insertQuery, values);
|
|
117
|
+
}
|
|
118
|
+
async postManyWithoutReturn(entities) {
|
|
119
|
+
// TODO: PERFORM AN INSERT BUT NOT THE RETRIEVAL QUERY FOR PERFORMANCE
|
|
120
|
+
// TODO: THIS IS ACTUALLY NEEDED TO HELP WITH LARGE DATASETS
|
|
121
|
+
this.throwNotImplemented('postManyWithoutReturn');
|
|
122
|
+
}
|
|
123
|
+
throwNotImplemented(feature) {
|
|
124
|
+
throw new common_1.NotImplementedException(`RedshiftRepository of type "${this.entityType?.name}" has no implementation for "${feature}"`);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
exports.RedshiftRepository = RedshiftRepository;
|
|
128
|
+
exports.RedshiftRepository = RedshiftRepository = __decorate([
|
|
129
|
+
(0, common_1.Injectable)(),
|
|
130
|
+
__metadata("design:paramtypes", [Object, typeorm_1.EntityManager])
|
|
131
|
+
], RedshiftRepository);
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
2
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
3
|
import { IEntityProvider } from '../types/entity-provider.interface';
|
|
4
|
+
import { TKeysOf } from '@onivoro/isomorphic-common';
|
|
5
|
+
import { TTableMeta } from '../types/table-meta.type';
|
|
4
6
|
export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEntity, FindOneOptions<TEntity>, FindManyOptions<TEntity>, FindOptionsWhere<TEntity>, QueryDeepPartialEntity<TEntity>> {
|
|
5
|
-
|
|
7
|
+
entityType: any;
|
|
6
8
|
entityManager: EntityManager;
|
|
9
|
+
protected columns: TKeysOf<TEntity, TTableMeta>;
|
|
10
|
+
protected table: string;
|
|
11
|
+
debug: boolean;
|
|
7
12
|
constructor(entityType: any, entityManager: EntityManager);
|
|
8
13
|
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
9
14
|
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
@@ -18,4 +23,31 @@ export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEnti
|
|
|
18
23
|
get repo(): import("typeorm").Repository<import("typeorm").ObjectLiteral>;
|
|
19
24
|
protected insertAndReturn(entityToInsert: TEntity): Promise<TEntity>;
|
|
20
25
|
protected insertAndReturnMany(entitiesToInsert: TEntity[]): Promise<TEntity[]>;
|
|
26
|
+
protected buildSelectStatement(options: FindManyOptions<TEntity>): {
|
|
27
|
+
query: string;
|
|
28
|
+
queryParams: any[];
|
|
29
|
+
};
|
|
30
|
+
protected buildDeleteStatement(where: FindManyOptions<TEntity>): {
|
|
31
|
+
query: string;
|
|
32
|
+
queryParams: any[];
|
|
33
|
+
};
|
|
34
|
+
protected buildWhereExpression(where?: FindOptionsWhere<TEntity>): {
|
|
35
|
+
queryParams: any[];
|
|
36
|
+
whereClause: string;
|
|
37
|
+
};
|
|
38
|
+
protected buildInsertQuery(entity: Partial<TEntity>): {
|
|
39
|
+
insertQuery: string;
|
|
40
|
+
values: any[];
|
|
41
|
+
};
|
|
42
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
43
|
+
insertQuery: string;
|
|
44
|
+
values: any[];
|
|
45
|
+
};
|
|
46
|
+
protected buildSelectManyQuery(entities: Partial<TEntity>[]): {
|
|
47
|
+
selectQuery: string;
|
|
48
|
+
values: any[];
|
|
49
|
+
};
|
|
50
|
+
map(raw: any): TEntity;
|
|
51
|
+
query(query: string, parameters: any[]): Promise<any[]>;
|
|
52
|
+
queryAndMap(query: string, parameters: any[]): Promise<TEntity[]>;
|
|
21
53
|
}
|
|
@@ -4,12 +4,21 @@ exports.TypeOrmRepository = void 0;
|
|
|
4
4
|
class TypeOrmRepository {
|
|
5
5
|
entityType;
|
|
6
6
|
entityManager;
|
|
7
|
+
columns = {};
|
|
8
|
+
table;
|
|
9
|
+
debug = false;
|
|
7
10
|
constructor(entityType, entityManager) {
|
|
8
11
|
this.entityType = entityType;
|
|
9
12
|
this.entityManager = entityManager;
|
|
13
|
+
const { tableName } = this.repo.metadata;
|
|
14
|
+
this.table = tableName;
|
|
15
|
+
this.repo.metadata.columns.forEach((_) => {
|
|
16
|
+
const { databasePath, propertyPath, type, isPrimary } = _;
|
|
17
|
+
this.columns[propertyPath] = { databasePath, type, propertyPath, isPrimary, default: _.default };
|
|
18
|
+
});
|
|
10
19
|
}
|
|
11
20
|
forTransaction(entityManager) {
|
|
12
|
-
return
|
|
21
|
+
return new this.constructor(this.entityType, entityManager);
|
|
13
22
|
}
|
|
14
23
|
async getMany(options) {
|
|
15
24
|
return await this.repo.find(options);
|
|
@@ -58,5 +67,103 @@ class TypeOrmRepository {
|
|
|
58
67
|
const insertedEntity = insertionResult.generatedMaps;
|
|
59
68
|
return insertedEntity;
|
|
60
69
|
}
|
|
70
|
+
buildSelectStatement(options) {
|
|
71
|
+
const { whereClause, queryParams } = this.buildWhereExpression(options.where);
|
|
72
|
+
const query = `SELECT * FROM "${this.table}"${whereClause};`;
|
|
73
|
+
return { query, queryParams };
|
|
74
|
+
}
|
|
75
|
+
buildDeleteStatement(where) {
|
|
76
|
+
const { whereClause, queryParams } = this.buildWhereExpression(where);
|
|
77
|
+
const query = `DELETE FROM "${this.table}"${whereClause};`;
|
|
78
|
+
return { query, queryParams };
|
|
79
|
+
}
|
|
80
|
+
buildWhereExpression(where) {
|
|
81
|
+
const queryParams = [];
|
|
82
|
+
let whereClause = '';
|
|
83
|
+
Object.entries(where || {}).forEach(([propertyPath, value], index) => {
|
|
84
|
+
const key = this.columns[propertyPath].databasePath;
|
|
85
|
+
if (index === 0) {
|
|
86
|
+
whereClause += ` WHERE ${key} = $${index + 1}`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
whereClause += ` AND ${key} = $${index + 1}`;
|
|
90
|
+
}
|
|
91
|
+
queryParams.push(value);
|
|
92
|
+
});
|
|
93
|
+
return { queryParams, whereClause };
|
|
94
|
+
}
|
|
95
|
+
buildInsertQuery(entity) {
|
|
96
|
+
const keys = Object.keys(entity);
|
|
97
|
+
const values = Object.values(entity);
|
|
98
|
+
const columnNames = keys.map(key => this.columns[key].databasePath).join(', ');
|
|
99
|
+
const paramPlaceholders = keys.map((_, index) => `$${index + 1}`).join(', ');
|
|
100
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES (${paramPlaceholders})`;
|
|
101
|
+
return { insertQuery, values };
|
|
102
|
+
}
|
|
103
|
+
buildInsertManyQuery(entities) {
|
|
104
|
+
const keyMap = {};
|
|
105
|
+
entities.forEach(entity => {
|
|
106
|
+
Object.keys(entity)
|
|
107
|
+
.forEach(key => {
|
|
108
|
+
keyMap[key] = true;
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
const columnNames = Object.keys(keyMap).map(key => this.columns[key].databasePath).join(', ');
|
|
112
|
+
const valuesExpressions = [];
|
|
113
|
+
const values = [];
|
|
114
|
+
entities.forEach(entity => {
|
|
115
|
+
const length = values.length;
|
|
116
|
+
Object.keys(keyMap).forEach(key => {
|
|
117
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
118
|
+
});
|
|
119
|
+
const paramPlaceholders = Object.keys(keyMap).map((_, index) => `$${length + index + 1}`).join(', ');
|
|
120
|
+
valuesExpressions.push(`(${paramPlaceholders})`);
|
|
121
|
+
});
|
|
122
|
+
const insertQuery = `INSERT INTO "${this.table}" (${columnNames}) VALUES ${valuesExpressions.join(', ')}`;
|
|
123
|
+
return { insertQuery, values };
|
|
124
|
+
}
|
|
125
|
+
buildSelectManyQuery(entities) {
|
|
126
|
+
const keyMap = {};
|
|
127
|
+
entities.forEach(entity => {
|
|
128
|
+
Object.keys(entity)
|
|
129
|
+
.forEach(key => {
|
|
130
|
+
keyMap[key] = true;
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
const selectExpressions = [];
|
|
134
|
+
const values = [];
|
|
135
|
+
entities.forEach(entity => {
|
|
136
|
+
const length = values.length;
|
|
137
|
+
Object.keys(keyMap).forEach(key => {
|
|
138
|
+
values.push((typeof entity[key] === 'undefined') ? this.columns[key].default : entity[key]);
|
|
139
|
+
});
|
|
140
|
+
const whereExpression = Object.keys(keyMap).map((_, index) => `(${this.columns[_].databasePath} = $${length + index + 1})`).join(' AND ');
|
|
141
|
+
selectExpressions.push(`(select * from "${this.table}" where (${whereExpression}))`);
|
|
142
|
+
});
|
|
143
|
+
const selectQuery = selectExpressions.join(' UNION ');
|
|
144
|
+
return { selectQuery, values };
|
|
145
|
+
}
|
|
146
|
+
map(raw) {
|
|
147
|
+
const mapped = Object.values(this.columns)
|
|
148
|
+
.reduce((entity, { propertyPath, databasePath, type }) => {
|
|
149
|
+
entity[propertyPath] = raw[databasePath];
|
|
150
|
+
return entity;
|
|
151
|
+
}, {});
|
|
152
|
+
return mapped;
|
|
153
|
+
}
|
|
154
|
+
async query(query, parameters) {
|
|
155
|
+
if (this.debug) {
|
|
156
|
+
console.log({ table: this.table, query, parameters });
|
|
157
|
+
}
|
|
158
|
+
const result = await this.repo.query(query, parameters);
|
|
159
|
+
if (this.debug) {
|
|
160
|
+
console.log({ table: this.table, query, parameters, result });
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
async queryAndMap(query, parameters) {
|
|
165
|
+
const result = await this.query(query, parameters);
|
|
166
|
+
return result?.map((_) => this.map(_));
|
|
167
|
+
}
|
|
61
168
|
}
|
|
62
169
|
exports.TypeOrmRepository = TypeOrmRepository;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const NullableTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const NullableTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const TableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const TableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const Table: (EntityClass: {
|
|
2
2
|
name: string;
|
|
3
|
-
}) => <TFunction extends Function, Y>(target:
|
|
3
|
+
}) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dataSourceConfigFactory =
|
|
3
|
+
exports.dataSourceConfigFactory = dataSourceConfigFactory;
|
|
4
4
|
const typeorm_naming_strategies_1 = require("typeorm-naming-strategies");
|
|
5
5
|
function dataSourceConfigFactory(name, options, entities) {
|
|
6
6
|
const { ca, database, host, password, port, username, synchronize = false, logging = false } = options;
|
|
@@ -22,4 +22,3 @@ function dataSourceConfigFactory(name, options, entities) {
|
|
|
22
22
|
};
|
|
23
23
|
return config;
|
|
24
24
|
}
|
|
25
|
-
exports.dataSourceConfigFactory = dataSourceConfigFactory;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateDateQuery =
|
|
3
|
+
exports.generateDateQuery = generateDateQuery;
|
|
4
4
|
const typeorm_1 = require("typeorm");
|
|
5
5
|
function generateDateQuery(minDueDate, maxDueDate) {
|
|
6
6
|
if (minDueDate && maxDueDate) {
|
|
@@ -14,4 +14,3 @@ function generateDateQuery(minDueDate, maxDueDate) {
|
|
|
14
14
|
}
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
|
-
exports.generateDateQuery = generateDateQuery;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getApiTypeFromColumn =
|
|
3
|
+
exports.getApiTypeFromColumn = getApiTypeFromColumn;
|
|
4
4
|
function getApiTypeFromColumn(columnType) {
|
|
5
5
|
if (!columnType) {
|
|
6
6
|
return 'string';
|
|
@@ -12,4 +12,3 @@ function getApiTypeFromColumn(columnType) {
|
|
|
12
12
|
return 'string';
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
exports.getApiTypeFromColumn = getApiTypeFromColumn;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPagingKey =
|
|
3
|
+
exports.getPagingKey = getPagingKey;
|
|
4
4
|
function getPagingKey(pageSize, skip, total) {
|
|
5
5
|
return pageSize * skip < total ? skip + 1 : undefined;
|
|
6
6
|
}
|
|
7
|
-
exports.getPagingKey = getPagingKey;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.removeFalseyKeys =
|
|
3
|
+
exports.removeFalseyKeys = removeFalseyKeys;
|
|
4
4
|
function removeFalseyKeys(obj) {
|
|
5
5
|
return Object.entries(obj)
|
|
6
6
|
.filter(([k, v]) => typeof v !== 'undefined')
|
|
@@ -9,4 +9,3 @@ function removeFalseyKeys(obj) {
|
|
|
9
9
|
return acc;
|
|
10
10
|
}, {});
|
|
11
11
|
}
|
|
12
|
-
exports.removeFalseyKeys = removeFalseyKeys;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColumnType } from "typeorm";
|
|
2
|
+
import { ColumnMetadata } from "typeorm/metadata/ColumnMetadata.js";
|
|
3
|
+
export type TTableMeta = {
|
|
4
|
+
databasePath: string;
|
|
5
|
+
type: ColumnType;
|
|
6
|
+
propertyPath: string;
|
|
7
|
+
isPrimary: boolean;
|
|
8
|
+
default: ColumnMetadata['default'];
|
|
9
|
+
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './lib/classes/columns-migration-base.class';
|
|
|
3
3
|
export * from './lib/classes/drop-column-migration-base.class';
|
|
4
4
|
export * from './lib/classes/drop-table-migration-base.class';
|
|
5
5
|
export * from './lib/classes/index-migration-base.class';
|
|
6
|
+
export * from './lib/classes/redshift-repository.class';
|
|
6
7
|
export * from './lib/classes/sql-writer.class';
|
|
7
8
|
export * from './lib/classes/table-migration-base.class';
|
|
8
9
|
export * from './lib/classes/type-orm-paging-repository.class';
|
|
@@ -23,4 +24,5 @@ export * from './lib/types/data-source-options.interface';
|
|
|
23
24
|
export * from './lib/types/entity-provider.interface';
|
|
24
25
|
export * from './lib/types/page-params.interface';
|
|
25
26
|
export * from './lib/types/paged-data.interface';
|
|
27
|
+
export * from './lib/types/table-meta.type';
|
|
26
28
|
export * from './lib/server-typeorm-postgres.module';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
|
+
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
|
+
import { TypeOrmRepository } from './type-orm-repository.class';
|
|
4
|
+
export declare class RedshiftRepository<TEntity> extends TypeOrmRepository<TEntity> {
|
|
5
|
+
entityType: any;
|
|
6
|
+
entityManager: EntityManager;
|
|
7
|
+
constructor(entityType: any, entityManager: EntityManager);
|
|
8
|
+
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
9
|
+
getOne(options: FindOneOptions<TEntity>): Promise<TEntity>;
|
|
10
|
+
delete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
11
|
+
patch(where: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
12
|
+
postOne(entity: Partial<TEntity>): Promise<TEntity>;
|
|
13
|
+
postMany(entities: Partial<TEntity>[]): Promise<TEntity[]>;
|
|
14
|
+
put(options: FindOptionsWhere<TEntity>, body: QueryDeepPartialEntity<TEntity>): Promise<void>;
|
|
15
|
+
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
16
|
+
getManyAndCount(options: FindManyOptions<TEntity>): Promise<[TEntity[], number]>;
|
|
17
|
+
softDelete(where: FindOptionsWhere<TEntity>): Promise<void>;
|
|
18
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
19
|
+
insertQuery: string;
|
|
20
|
+
values: any[];
|
|
21
|
+
};
|
|
22
|
+
private mapPlaceholderExpression;
|
|
23
|
+
postOneWithoutReturn(entity: Partial<TEntity>): Promise<void>;
|
|
24
|
+
postManyWithoutReturn(entities: Partial<TEntity>[]): Promise<void>;
|
|
25
|
+
private throwNotImplemented;
|
|
26
|
+
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { EntityManager, FindManyOptions, FindOneOptions, FindOptionsWhere } from 'typeorm';
|
|
2
2
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
|
3
3
|
import { IEntityProvider } from '../types/entity-provider.interface';
|
|
4
|
+
import { TKeysOf } from '@onivoro/isomorphic-common';
|
|
5
|
+
import { TTableMeta } from '../types/table-meta.type';
|
|
4
6
|
export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEntity, FindOneOptions<TEntity>, FindManyOptions<TEntity>, FindOptionsWhere<TEntity>, QueryDeepPartialEntity<TEntity>> {
|
|
5
|
-
|
|
7
|
+
entityType: any;
|
|
6
8
|
entityManager: EntityManager;
|
|
9
|
+
protected columns: TKeysOf<TEntity, TTableMeta>;
|
|
10
|
+
protected table: string;
|
|
11
|
+
debug: boolean;
|
|
7
12
|
constructor(entityType: any, entityManager: EntityManager);
|
|
8
13
|
forTransaction(entityManager: EntityManager): TypeOrmRepository<TEntity>;
|
|
9
14
|
getMany(options: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
@@ -18,4 +23,31 @@ export declare class TypeOrmRepository<TEntity> implements IEntityProvider<TEnti
|
|
|
18
23
|
get repo(): import("typeorm").Repository<import("typeorm").ObjectLiteral>;
|
|
19
24
|
protected insertAndReturn(entityToInsert: TEntity): Promise<TEntity>;
|
|
20
25
|
protected insertAndReturnMany(entitiesToInsert: TEntity[]): Promise<TEntity[]>;
|
|
26
|
+
protected buildSelectStatement(options: FindManyOptions<TEntity>): {
|
|
27
|
+
query: string;
|
|
28
|
+
queryParams: any[];
|
|
29
|
+
};
|
|
30
|
+
protected buildDeleteStatement(where: FindManyOptions<TEntity>): {
|
|
31
|
+
query: string;
|
|
32
|
+
queryParams: any[];
|
|
33
|
+
};
|
|
34
|
+
protected buildWhereExpression(where?: FindOptionsWhere<TEntity>): {
|
|
35
|
+
queryParams: any[];
|
|
36
|
+
whereClause: string;
|
|
37
|
+
};
|
|
38
|
+
protected buildInsertQuery(entity: Partial<TEntity>): {
|
|
39
|
+
insertQuery: string;
|
|
40
|
+
values: any[];
|
|
41
|
+
};
|
|
42
|
+
protected buildInsertManyQuery(entities: Partial<TEntity>[]): {
|
|
43
|
+
insertQuery: string;
|
|
44
|
+
values: any[];
|
|
45
|
+
};
|
|
46
|
+
protected buildSelectManyQuery(entities: Partial<TEntity>[]): {
|
|
47
|
+
selectQuery: string;
|
|
48
|
+
values: any[];
|
|
49
|
+
};
|
|
50
|
+
map(raw: any): TEntity;
|
|
51
|
+
query(query: string, parameters: any[]): Promise<any[]>;
|
|
52
|
+
queryAndMap(query: string, parameters: any[]): Promise<TEntity[]>;
|
|
21
53
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const NullableTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const NullableTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const PrimaryTableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { ColumnOptions } from "typeorm";
|
|
2
|
-
export declare const TableColumn: (options?: Pick<ColumnOptions,
|
|
2
|
+
export declare const TableColumn: (options?: Pick<ColumnOptions, "type">) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const Table: (EntityClass: {
|
|
2
2
|
name: string;
|
|
3
|
-
}) => <TFunction extends Function, Y>(target:
|
|
3
|
+
}) => <TFunction extends Function, Y>(target: TFunction | object, propertyKey?: string | symbol, descriptor?: TypedPropertyDescriptor<Y>) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ColumnType } from "typeorm";
|
|
2
|
+
import { ColumnMetadata } from "typeorm/metadata/ColumnMetadata.js";
|
|
3
|
+
export type TTableMeta = {
|
|
4
|
+
databasePath: string;
|
|
5
|
+
type: ColumnType;
|
|
6
|
+
propertyPath: string;
|
|
7
|
+
isPrimary: boolean;
|
|
8
|
+
default: ColumnMetadata['default'];
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onivoro/server-typeorm-postgres",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "22.0.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "git+https://github.com/onivoro/server-typeorm-postgres.git"
|
|
6
6
|
},
|
|
@@ -30,19 +30,19 @@
|
|
|
30
30
|
"module": ""
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@onivoro/cli": "
|
|
33
|
+
"@onivoro/cli": "^22.0.3",
|
|
34
34
|
"@types/jest": "*",
|
|
35
|
-
"@types/node": "
|
|
35
|
+
"@types/node": "22.7.9",
|
|
36
36
|
"typescript": "*"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
|
-
"node": "
|
|
40
|
-
"npm": "10.
|
|
39
|
+
"node": "22.10.0",
|
|
40
|
+
"npm": "10.9.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@nestjs/common": "^10.4.
|
|
43
|
+
"@nestjs/common": "^10.4.6",
|
|
44
44
|
"@nestjs/swagger": "^7.4.2",
|
|
45
|
-
"@onivoro/isomorphic-common": "^0.
|
|
45
|
+
"@onivoro/isomorphic-common": "^22.0.1",
|
|
46
46
|
"typeorm": "^0.3.20",
|
|
47
47
|
"typeorm-naming-strategies": "^4.1.0"
|
|
48
48
|
}
|