@rsdk/db.mikro-orm 5.12.0-next.7 → 5.12.0-next.8
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/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/mikro-orm.plugin.d.ts +8 -0
- package/dist/mikro-orm.plugin.js +92 -9
- package/dist/mikro-orm.plugin.js.map +1 -1
- package/dist/providers/mikro-orm.config.d.ts +3 -2
- package/dist/providers/mikro-orm.config.js +21 -3
- package/dist/providers/mikro-orm.config.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/mikro-orm.plugin.ts +105 -11
- package/src/providers/mikro-orm.config.ts +20 -5
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MikroOrmPlugin = void 0;
|
|
3
|
+
exports.MikroOrmPluginConfig = exports.MikroOrmPlugin = void 0;
|
|
4
4
|
var mikro_orm_plugin_1 = require("./mikro-orm.plugin");
|
|
5
5
|
Object.defineProperty(exports, "MikroOrmPlugin", { enumerable: true, get: function () { return mikro_orm_plugin_1.MikroOrmPlugin; } });
|
|
6
|
+
var mikro_orm_config_1 = require("./providers/mikro-orm.config");
|
|
7
|
+
Object.defineProperty(exports, "MikroOrmPluginConfig", { enumerable: true, get: function () { return mikro_orm_config_1.MikroOrmPluginConfig; } });
|
|
6
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAAoD;AAA3C,kHAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAAoD;AAA3C,kHAAA,cAAc,OAAA;AACvB,iEAAoE;AAA3D,wHAAA,oBAAoB,OAAA"}
|
|
@@ -5,11 +5,19 @@ import type { MikroOrmPluginOptions } from './types';
|
|
|
5
5
|
export declare class MikroOrmPlugin implements PlatformAppPlugin {
|
|
6
6
|
private readonly options;
|
|
7
7
|
private static readonly logger;
|
|
8
|
+
private static cachedPostgresDriverCtor;
|
|
8
9
|
/**
|
|
9
10
|
* По умолчанию парсит тип драйвера из env %PACKAGE_NAME%_DB_URL
|
|
10
11
|
*/
|
|
11
12
|
constructor(options: MikroOrmPluginOptions);
|
|
12
13
|
get entities(): (string | any)[] | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Возвращает ссылку на `PostgreSqlDriver` из @mikro-orm/postgresql, если
|
|
16
|
+
* пакет установлен. Lazy-require, чтобы не подтягивать @mikro-orm/postgresql
|
|
17
|
+
* при использовании mysql/sqlite/etc. Сравнение по reference строгое: если
|
|
18
|
+
* пользователь унаследует свой класс, нужен явный `type: 'postgresql'`.
|
|
19
|
+
*/
|
|
20
|
+
private static getPostgresDriverCtor;
|
|
13
21
|
forTransports(): AppropriateTransports;
|
|
14
22
|
modules(): (Constructor | DynamicModule | Promise<DynamicModule>)[];
|
|
15
23
|
errorTransformers(): IErrorsTransformer[];
|
package/dist/mikro-orm.plugin.js
CHANGED
|
@@ -19,6 +19,7 @@ const providers_1 = require("./providers");
|
|
|
19
19
|
class MikroOrmPlugin {
|
|
20
20
|
options;
|
|
21
21
|
static logger = logging_1.LoggerFactory.create(MikroOrmPlugin);
|
|
22
|
+
static cachedPostgresDriverCtor;
|
|
22
23
|
/**
|
|
23
24
|
* По умолчанию парсит тип драйвера из env %PACKAGE_NAME%_DB_URL
|
|
24
25
|
*/
|
|
@@ -28,6 +29,25 @@ class MikroOrmPlugin {
|
|
|
28
29
|
get entities() {
|
|
29
30
|
return this?.options?.entitiesTs;
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Возвращает ссылку на `PostgreSqlDriver` из @mikro-orm/postgresql, если
|
|
34
|
+
* пакет установлен. Lazy-require, чтобы не подтягивать @mikro-orm/postgresql
|
|
35
|
+
* при использовании mysql/sqlite/etc. Сравнение по reference строгое: если
|
|
36
|
+
* пользователь унаследует свой класс, нужен явный `type: 'postgresql'`.
|
|
37
|
+
*/
|
|
38
|
+
static getPostgresDriverCtor() {
|
|
39
|
+
if (MikroOrmPlugin.cachedPostgresDriverCtor !== undefined) {
|
|
40
|
+
return MikroOrmPlugin.cachedPostgresDriverCtor;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
MikroOrmPlugin.cachedPostgresDriverCtor =
|
|
44
|
+
require('@mikro-orm/postgresql').PostgreSqlDriver;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
MikroOrmPlugin.cachedPostgresDriverCtor = null;
|
|
48
|
+
}
|
|
49
|
+
return MikroOrmPlugin.cachedPostgresDriverCtor;
|
|
50
|
+
}
|
|
31
51
|
forTransports() {
|
|
32
52
|
return 'any';
|
|
33
53
|
}
|
|
@@ -46,10 +66,79 @@ class MikroOrmPlugin {
|
|
|
46
66
|
},
|
|
47
67
|
],
|
|
48
68
|
inject: [mikro_orm_config_1.MikroOrmPluginConfig, mikro_orm_logger_adapter_1.MikroOrmAdapter, core_1.APP_NAME],
|
|
49
|
-
useFactory: (config, logger, appName) => {
|
|
69
|
+
useFactory: async (config, logger, appName) => {
|
|
70
|
+
const ssl = (0, db_1.getSecureContextOptions)(config);
|
|
71
|
+
/**
|
|
72
|
+
* Тип распознаём двумя путями: устаревший `type === 'postgresql'`
|
|
73
|
+
* (для обратной совместимости) и `driver === PostgreSqlDriver` через
|
|
74
|
+
* lazy-require (актуальный API mikro-orm 6.x). Сравнение по reference
|
|
75
|
+
* строгое — наследники не активируют native путь.
|
|
76
|
+
*/
|
|
77
|
+
const isPostgresFamily = this.options.type === 'postgresql' ||
|
|
78
|
+
(this.options.driver !== undefined &&
|
|
79
|
+
this.options.driver === MikroOrmPlugin.getPostgresDriverCtor());
|
|
80
|
+
/**
|
|
81
|
+
* Probe передаётся только если фолбэк явно разрешён через env.
|
|
82
|
+
* Иначе resolveDbConnection упадёт с MultiHostNativeRequired при
|
|
83
|
+
* отсутствии pg-native — runtime failover не будет тихо потерян.
|
|
84
|
+
*/
|
|
85
|
+
const resolved = await (0, db_1.resolveDbConnection)({
|
|
86
|
+
url: config.url,
|
|
87
|
+
logger: MikroOrmPlugin.logger,
|
|
88
|
+
isPostgresFamily,
|
|
89
|
+
...(config.multiHostBootstrapFallback && {
|
|
90
|
+
bootstrapProbe: (candidate) => (0, db_1.pgProbe)(candidate, ssl),
|
|
91
|
+
}),
|
|
92
|
+
});
|
|
93
|
+
let clientUrl;
|
|
94
|
+
let driverOptions;
|
|
95
|
+
if (resolved.kind === 'native-libpq') {
|
|
96
|
+
/**
|
|
97
|
+
* mikro-orm сам парсит `clientUrl` через pg-connection-string —
|
|
98
|
+
* multi-host строку он не понимает и упадёт. Поэтому в clientUrl
|
|
99
|
+
* кладём косметический single-host (первый хост), а реальную
|
|
100
|
+
* multi-host строку отдаём через `driverOptions.connection.nativeConnectionString`.
|
|
101
|
+
*/
|
|
102
|
+
clientUrl = config.url.getHostAt(0).toString();
|
|
103
|
+
/**
|
|
104
|
+
* ⚠ DIRTY HACK / зависит от internal API mikro-orm — см. docs/md/TECHDEBT.md.
|
|
105
|
+
*
|
|
106
|
+
* mikro-orm/postgresql внутри жёстко использует `PostgreSqlKnexDialect`
|
|
107
|
+
* (см. node_modules/@mikro-orm/postgresql/PostgreSqlConnection.js),
|
|
108
|
+
* публичного hook'а для подмены dialect нет. Но `Utils.mergeConfig`
|
|
109
|
+
* (node_modules/@mikro-orm/core/utils/Utils.js) для не-plain-object
|
|
110
|
+
* значений делает overwrite через `Object.assign` — это позволяет
|
|
111
|
+
* перезаписать класс `PostgreSqlKnexDialect` строкой `'pgnative'`.
|
|
112
|
+
* Дальше @mikro-orm/knex вызывает `knex({ client: 'pgnative', ... })`,
|
|
113
|
+
* и путь становится идентичным нашему knex-плагину:
|
|
114
|
+
* `nativeConnectionString` идёт в libpq в обход pg-connection-string.
|
|
115
|
+
*
|
|
116
|
+
* При апгрейде mikro-orm прогоните `examples/db-multihost/example.mikro-orm`
|
|
117
|
+
* со сценарием failover из README — изменение поведения `Utils._merge`
|
|
118
|
+
* молча сломает native путь без exception.
|
|
119
|
+
*/
|
|
120
|
+
driverOptions = {
|
|
121
|
+
client: 'pgnative',
|
|
122
|
+
connection: {
|
|
123
|
+
nativeConnectionString: resolved.multiHostUrl,
|
|
124
|
+
keepAlive: config.keepAlive,
|
|
125
|
+
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
clientUrl = resolved.url.toString();
|
|
131
|
+
driverOptions = {
|
|
132
|
+
connection: {
|
|
133
|
+
keepAlive: config.keepAlive,
|
|
134
|
+
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
135
|
+
ssl,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
50
139
|
return (0, lodash_1.default)({
|
|
51
140
|
driver: this.options.driver ?? this.mapTypeToDriver(this.options.type),
|
|
52
|
-
clientUrl
|
|
141
|
+
clientUrl,
|
|
53
142
|
...(config.schema && {
|
|
54
143
|
schema: config.schema,
|
|
55
144
|
}),
|
|
@@ -67,13 +156,7 @@ class MikroOrmPlugin {
|
|
|
67
156
|
glob: '!(*.d).{js,ts}',
|
|
68
157
|
},
|
|
69
158
|
allowGlobalContext: true,
|
|
70
|
-
driverOptions
|
|
71
|
-
connection: {
|
|
72
|
-
keepAlive: config.keepAlive,
|
|
73
|
-
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
74
|
-
ssl: (0, db_1.getSecureContextOptions)(config),
|
|
75
|
-
},
|
|
76
|
-
},
|
|
159
|
+
driverOptions,
|
|
77
160
|
...this.options.overrideConfig,
|
|
78
161
|
})
|
|
79
162
|
.omitBy(lodash_1.default.isUndefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mikro-orm.plugin.js","sourceRoot":"","sources":["../src/mikro-orm.plugin.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,0DAA0D;;;;;;AAG1D,8CAAmD;AAQnD,qCAAuD;AACvD,
|
|
1
|
+
{"version":3,"file":"mikro-orm.plugin.js","sourceRoot":"","sources":["../src/mikro-orm.plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Config } from '@rsdk/core';
|
|
2
|
-
import { SslModeEnum } from '@rsdk/db';
|
|
2
|
+
import { MultiHostUrl, SslModeEnum } from '@rsdk/db';
|
|
3
3
|
export declare class MikroOrmPluginConfig extends Config {
|
|
4
|
-
url:
|
|
4
|
+
url: MultiHostUrl;
|
|
5
|
+
multiHostBootstrapFallback: boolean;
|
|
5
6
|
schema: string;
|
|
6
7
|
poolMin: number;
|
|
7
8
|
poolMax: number;
|
|
@@ -15,6 +15,7 @@ const core_1 = require("@rsdk/core");
|
|
|
15
15
|
const db_1 = require("@rsdk/db");
|
|
16
16
|
let MikroOrmPluginConfig = class MikroOrmPluginConfig extends core_1.Config {
|
|
17
17
|
url;
|
|
18
|
+
multiHostBootstrapFallback;
|
|
18
19
|
schema;
|
|
19
20
|
poolMin;
|
|
20
21
|
poolMax;
|
|
@@ -28,11 +29,28 @@ let MikroOrmPluginConfig = class MikroOrmPluginConfig extends core_1.Config {
|
|
|
28
29
|
};
|
|
29
30
|
exports.MikroOrmPluginConfig = MikroOrmPluginConfig;
|
|
30
31
|
__decorate([
|
|
31
|
-
(0, core_1.Property)('URL', new
|
|
32
|
-
description:
|
|
32
|
+
(0, core_1.Property)('URL', new db_1.MultiHostUrlParser(), {
|
|
33
|
+
description: (0, common_1.text) `
|
|
34
|
+
Database server url. Supports multi-host syntax for Postgres:
|
|
35
|
+
\`postgres://user:pass@host1:5432,host2:5432/db\`. Port is optional (driver default, e.g. 5432 for PostgreSQL).
|
|
36
|
+
With \`pg-native\` installed RSDK uses libpq runtime failover. Without \`pg-native\`
|
|
37
|
+
the app fails fast at startup unless DB_MULTIHOST_BOOTSTRAP_FALLBACK=true is set.
|
|
38
|
+
See docs/md/DATABASES.md for details.
|
|
39
|
+
`,
|
|
33
40
|
}),
|
|
34
|
-
__metadata("design:type",
|
|
41
|
+
__metadata("design:type", db_1.MultiHostUrl)
|
|
35
42
|
], MikroOrmPluginConfig.prototype, "url", void 0);
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, core_1.Property)('MULTIHOST_BOOTSTRAP_FALLBACK', new core_1.BoolParser(), {
|
|
45
|
+
defaultValue: false,
|
|
46
|
+
description: (0, common_1.text) `
|
|
47
|
+
Allows silent fallback to bootstrap-resolve when DB_URL has multiple
|
|
48
|
+
hosts but \`pg-native\` is not installed. When false (default) the app
|
|
49
|
+
fails fast at startup so that runtime failover is never quietly downgraded.
|
|
50
|
+
`,
|
|
51
|
+
}),
|
|
52
|
+
__metadata("design:type", Boolean)
|
|
53
|
+
], MikroOrmPluginConfig.prototype, "multiHostBootstrapFallback", void 0);
|
|
36
54
|
__decorate([
|
|
37
55
|
(0, core_1.Property)('SCHEMA', new core_1.StringParser(), {
|
|
38
56
|
description: (0, common_1.text) `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mikro-orm.config.js","sourceRoot":"","sources":["../../src/providers/mikro-orm.config.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"mikro-orm.config.js","sourceRoot":"","sources":["../../src/providers/mikro-orm.config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/db.mikro-orm",
|
|
3
|
-
"version": "5.12.0-next.
|
|
3
|
+
"version": "5.12.0-next.8",
|
|
4
4
|
"description": "Mikro-orm module for platform",
|
|
5
5
|
"license": "Apache License 2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"optional": true
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "ce0adb86b9bafb8df462e4eb47600c8bb08cc7df"
|
|
60
60
|
}
|
package/src/index.ts
CHANGED
package/src/mikro-orm.plugin.ts
CHANGED
|
@@ -11,7 +11,11 @@ import type {
|
|
|
11
11
|
PlatformAppPlugin,
|
|
12
12
|
} from '@rsdk/core';
|
|
13
13
|
import { APP_NAME, NoInitException } from '@rsdk/core';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
getSecureContextOptions,
|
|
16
|
+
pgProbe,
|
|
17
|
+
resolveDbConnection,
|
|
18
|
+
} from '@rsdk/db';
|
|
15
19
|
import { LoggerFactory } from '@rsdk/logging';
|
|
16
20
|
import _ from 'lodash';
|
|
17
21
|
import path from 'node:path';
|
|
@@ -24,6 +28,7 @@ import type { DriverType, MikroOrmPluginOptions } from './types';
|
|
|
24
28
|
|
|
25
29
|
export class MikroOrmPlugin implements PlatformAppPlugin {
|
|
26
30
|
private static readonly logger = LoggerFactory.create(MikroOrmPlugin);
|
|
31
|
+
private static cachedPostgresDriverCtor: unknown;
|
|
27
32
|
|
|
28
33
|
/**
|
|
29
34
|
* По умолчанию парсит тип драйвера из env %PACKAGE_NAME%_DB_URL
|
|
@@ -34,6 +39,25 @@ export class MikroOrmPlugin implements PlatformAppPlugin {
|
|
|
34
39
|
return this?.options?.entitiesTs;
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Возвращает ссылку на `PostgreSqlDriver` из @mikro-orm/postgresql, если
|
|
44
|
+
* пакет установлен. Lazy-require, чтобы не подтягивать @mikro-orm/postgresql
|
|
45
|
+
* при использовании mysql/sqlite/etc. Сравнение по reference строгое: если
|
|
46
|
+
* пользователь унаследует свой класс, нужен явный `type: 'postgresql'`.
|
|
47
|
+
*/
|
|
48
|
+
private static getPostgresDriverCtor(): unknown {
|
|
49
|
+
if (MikroOrmPlugin.cachedPostgresDriverCtor !== undefined) {
|
|
50
|
+
return MikroOrmPlugin.cachedPostgresDriverCtor;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
MikroOrmPlugin.cachedPostgresDriverCtor =
|
|
54
|
+
require('@mikro-orm/postgresql').PostgreSqlDriver;
|
|
55
|
+
} catch {
|
|
56
|
+
MikroOrmPlugin.cachedPostgresDriverCtor = null;
|
|
57
|
+
}
|
|
58
|
+
return MikroOrmPlugin.cachedPostgresDriverCtor;
|
|
59
|
+
}
|
|
60
|
+
|
|
37
61
|
forTransports(): AppropriateTransports {
|
|
38
62
|
return 'any';
|
|
39
63
|
}
|
|
@@ -54,15 +78,91 @@ export class MikroOrmPlugin implements PlatformAppPlugin {
|
|
|
54
78
|
},
|
|
55
79
|
],
|
|
56
80
|
inject: [MikroOrmPluginConfig, MikroOrmAdapter, APP_NAME],
|
|
57
|
-
useFactory: (
|
|
81
|
+
useFactory: async (
|
|
58
82
|
config: MikroOrmPluginConfig,
|
|
59
83
|
logger: MikroOrmAdapter,
|
|
60
84
|
appName: string,
|
|
61
|
-
): MikroOrmModuleSyncOptions => {
|
|
85
|
+
): Promise<MikroOrmModuleSyncOptions> => {
|
|
86
|
+
const ssl = getSecureContextOptions(config);
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Тип распознаём двумя путями: устаревший `type === 'postgresql'`
|
|
90
|
+
* (для обратной совместимости) и `driver === PostgreSqlDriver` через
|
|
91
|
+
* lazy-require (актуальный API mikro-orm 6.x). Сравнение по reference
|
|
92
|
+
* строгое — наследники не активируют native путь.
|
|
93
|
+
*/
|
|
94
|
+
const isPostgresFamily =
|
|
95
|
+
this.options.type === 'postgresql' ||
|
|
96
|
+
(this.options.driver !== undefined &&
|
|
97
|
+
this.options.driver === MikroOrmPlugin.getPostgresDriverCtor());
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Probe передаётся только если фолбэк явно разрешён через env.
|
|
101
|
+
* Иначе resolveDbConnection упадёт с MultiHostNativeRequired при
|
|
102
|
+
* отсутствии pg-native — runtime failover не будет тихо потерян.
|
|
103
|
+
*/
|
|
104
|
+
const resolved = await resolveDbConnection({
|
|
105
|
+
url: config.url,
|
|
106
|
+
logger: MikroOrmPlugin.logger,
|
|
107
|
+
isPostgresFamily,
|
|
108
|
+
...(config.multiHostBootstrapFallback && {
|
|
109
|
+
bootstrapProbe: (candidate: URL): Promise<void> =>
|
|
110
|
+
pgProbe(candidate, ssl),
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
let clientUrl: string;
|
|
115
|
+
let driverOptions: Record<string, unknown>;
|
|
116
|
+
|
|
117
|
+
if (resolved.kind === 'native-libpq') {
|
|
118
|
+
/**
|
|
119
|
+
* mikro-orm сам парсит `clientUrl` через pg-connection-string —
|
|
120
|
+
* multi-host строку он не понимает и упадёт. Поэтому в clientUrl
|
|
121
|
+
* кладём косметический single-host (первый хост), а реальную
|
|
122
|
+
* multi-host строку отдаём через `driverOptions.connection.nativeConnectionString`.
|
|
123
|
+
*/
|
|
124
|
+
clientUrl = config.url.getHostAt(0).toString();
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* ⚠ DIRTY HACK / зависит от internal API mikro-orm — см. docs/md/TECHDEBT.md.
|
|
128
|
+
*
|
|
129
|
+
* mikro-orm/postgresql внутри жёстко использует `PostgreSqlKnexDialect`
|
|
130
|
+
* (см. node_modules/@mikro-orm/postgresql/PostgreSqlConnection.js),
|
|
131
|
+
* публичного hook'а для подмены dialect нет. Но `Utils.mergeConfig`
|
|
132
|
+
* (node_modules/@mikro-orm/core/utils/Utils.js) для не-plain-object
|
|
133
|
+
* значений делает overwrite через `Object.assign` — это позволяет
|
|
134
|
+
* перезаписать класс `PostgreSqlKnexDialect` строкой `'pgnative'`.
|
|
135
|
+
* Дальше @mikro-orm/knex вызывает `knex({ client: 'pgnative', ... })`,
|
|
136
|
+
* и путь становится идентичным нашему knex-плагину:
|
|
137
|
+
* `nativeConnectionString` идёт в libpq в обход pg-connection-string.
|
|
138
|
+
*
|
|
139
|
+
* При апгрейде mikro-orm прогоните `examples/db-multihost/example.mikro-orm`
|
|
140
|
+
* со сценарием failover из README — изменение поведения `Utils._merge`
|
|
141
|
+
* молча сломает native путь без exception.
|
|
142
|
+
*/
|
|
143
|
+
driverOptions = {
|
|
144
|
+
client: 'pgnative',
|
|
145
|
+
connection: {
|
|
146
|
+
nativeConnectionString: resolved.multiHostUrl,
|
|
147
|
+
keepAlive: config.keepAlive,
|
|
148
|
+
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
} else {
|
|
152
|
+
clientUrl = resolved.url.toString();
|
|
153
|
+
driverOptions = {
|
|
154
|
+
connection: {
|
|
155
|
+
keepAlive: config.keepAlive,
|
|
156
|
+
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
157
|
+
ssl,
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
62
162
|
return _(<MikroOrmModuleSyncOptions>{
|
|
63
163
|
driver:
|
|
64
164
|
this.options.driver ?? this.mapTypeToDriver(this.options.type),
|
|
65
|
-
clientUrl
|
|
165
|
+
clientUrl,
|
|
66
166
|
...(config.schema && {
|
|
67
167
|
schema: config.schema,
|
|
68
168
|
}),
|
|
@@ -80,13 +180,7 @@ export class MikroOrmPlugin implements PlatformAppPlugin {
|
|
|
80
180
|
glob: '!(*.d).{js,ts}',
|
|
81
181
|
},
|
|
82
182
|
allowGlobalContext: true,
|
|
83
|
-
driverOptions
|
|
84
|
-
connection: {
|
|
85
|
-
keepAlive: config.keepAlive,
|
|
86
|
-
keepAliveInitialDelay: config.keepAliveInitialDelay,
|
|
87
|
-
ssl: getSecureContextOptions(config),
|
|
88
|
-
},
|
|
89
|
-
},
|
|
183
|
+
driverOptions,
|
|
90
184
|
...(this.options.overrideConfig as any),
|
|
91
185
|
})
|
|
92
186
|
.omitBy(_.isUndefined)
|
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
IntParser,
|
|
9
9
|
Property,
|
|
10
10
|
StringParser,
|
|
11
|
-
UrlParser,
|
|
12
11
|
} from '@rsdk/core';
|
|
13
|
-
import { SslModeEnum } from '@rsdk/db';
|
|
12
|
+
import { MultiHostUrl, MultiHostUrlParser, SslModeEnum } from '@rsdk/db';
|
|
14
13
|
|
|
15
14
|
@ConfigSection({
|
|
16
15
|
name: 'mikro-orm database config',
|
|
@@ -18,10 +17,26 @@ import { SslModeEnum } from '@rsdk/db';
|
|
|
18
17
|
prefix: 'DB',
|
|
19
18
|
})
|
|
20
19
|
export class MikroOrmPluginConfig extends Config {
|
|
21
|
-
@Property('URL', new
|
|
22
|
-
description:
|
|
20
|
+
@Property('URL', new MultiHostUrlParser(), {
|
|
21
|
+
description: text`
|
|
22
|
+
Database server url. Supports multi-host syntax for Postgres:
|
|
23
|
+
\`postgres://user:pass@host1:5432,host2:5432/db\`. Port is optional (driver default, e.g. 5432 for PostgreSQL).
|
|
24
|
+
With \`pg-native\` installed RSDK uses libpq runtime failover. Without \`pg-native\`
|
|
25
|
+
the app fails fast at startup unless DB_MULTIHOST_BOOTSTRAP_FALLBACK=true is set.
|
|
26
|
+
See docs/md/DATABASES.md for details.
|
|
27
|
+
`,
|
|
28
|
+
})
|
|
29
|
+
url!: MultiHostUrl;
|
|
30
|
+
|
|
31
|
+
@Property('MULTIHOST_BOOTSTRAP_FALLBACK', new BoolParser(), {
|
|
32
|
+
defaultValue: false,
|
|
33
|
+
description: text`
|
|
34
|
+
Allows silent fallback to bootstrap-resolve when DB_URL has multiple
|
|
35
|
+
hosts but \`pg-native\` is not installed. When false (default) the app
|
|
36
|
+
fails fast at startup so that runtime failover is never quietly downgraded.
|
|
37
|
+
`,
|
|
23
38
|
})
|
|
24
|
-
|
|
39
|
+
multiHostBootstrapFallback!: boolean;
|
|
25
40
|
|
|
26
41
|
@Property('SCHEMA', new StringParser(), {
|
|
27
42
|
description: text`
|