@privateaim/server-db-kit 0.8.26 → 0.8.28
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 +25 -0
- package/dist/data-source/index.d.ts +2 -0
- package/dist/data-source/index.d.ts.map +1 -0
- package/dist/data-source/options.d.ts +14 -0
- package/dist/data-source/options.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +75 -3
- package/dist/index.mjs.map +1 -1
- package/dist/subscriber/base.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/data-source/index.ts +8 -0
- package/src/data-source/options.ts +103 -0
- package/src/index.ts +2 -1
- package/src/subscriber/base.ts +13 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.8.28](https://github.com/PrivateAIM/hub/compare/v0.8.27...v0.8.28) (2026-02-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* database migration capabilities ([#1437](https://github.com/PrivateAIM/hub/issues/1437)) ([ada0c8c](https://github.com/PrivateAIM/hub/commit/ada0c8c82c50d7ff999c60d7d6b8a6aea10064f0))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @privateaim/kit bumped from ^0.8.27 to ^0.8.28
|
|
16
|
+
* @privateaim/server-kit bumped from ^0.8.27 to ^0.8.28
|
|
17
|
+
|
|
18
|
+
## [0.8.27](https://github.com/PrivateAIM/hub/compare/v0.8.26...v0.8.27) (2026-02-12)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
* The following workspace dependencies were updated
|
|
24
|
+
* dependencies
|
|
25
|
+
* @privateaim/kit bumped from ^0.8.26 to ^0.8.27
|
|
26
|
+
* @privateaim/server-kit bumped from ^0.8.26 to ^0.8.27
|
|
27
|
+
|
|
3
28
|
## [0.8.26](https://github.com/PrivateAIM/hub/compare/v0.8.25...v0.8.26) (2026-02-11)
|
|
4
29
|
|
|
5
30
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data-source/index.ts"],"names":[],"mappings":"AAOA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DataSourceOptions } from 'typeorm';
|
|
2
|
+
export type DataSourceOptionsEntities = DataSourceOptions['entities'];
|
|
3
|
+
export type DataSourceOptionsSubscribers = DataSourceOptions['subscribers'];
|
|
4
|
+
export declare class DataSourceOptionsBuilder {
|
|
5
|
+
protected entities: DataSourceOptionsEntities;
|
|
6
|
+
protected subscribers: DataSourceOptionsSubscribers;
|
|
7
|
+
constructor();
|
|
8
|
+
buildWithEnv(): DataSourceOptions;
|
|
9
|
+
buildWith(options: DataSourceOptions): DataSourceOptions;
|
|
10
|
+
setEntities(entities: DataSourceOptionsEntities): void;
|
|
11
|
+
setSubscribers(subscribers: DataSourceOptionsSubscribers): void;
|
|
12
|
+
protected normalize(options: DataSourceOptions): DataSourceOptions;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/data-source/options.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAQjD,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;AACtE,MAAM,MAAM,4BAA4B,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAE5E,qBAAa,wBAAwB;IACjC,SAAS,CAAC,QAAQ,EAAG,yBAAyB,CAAC;IAE/C,SAAS,CAAC,WAAW,EAAG,4BAA4B,CAAC;;IAWrD,YAAY;IAUZ,SAAS,CAAC,OAAO,EAAE,iBAAiB;IAMpC,WAAW,CAAC,QAAQ,EAAE,yBAAyB;IAI/C,cAAc,CAAC,WAAW,EAAE,4BAA4B;IAMxD,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,iBAAiB,GAAI,iBAAiB;CA4CtE"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
|
+
import { readDataSourceOptionsFromEnv, isCodeTransformation, CodeTransformation, transformFilePath } from 'typeorm-extension';
|
|
1
2
|
import { DomainEventName } from '@privateaim/kit';
|
|
2
|
-
import { useEntityEventPublisher } from '@privateaim/server-kit';
|
|
3
|
+
import { isEntityEventPublisherUsable, useEntityEventPublisher } from '@privateaim/server-kit';
|
|
4
|
+
|
|
5
|
+
class DataSourceOptionsBuilder {
|
|
6
|
+
entities;
|
|
7
|
+
subscribers;
|
|
8
|
+
// ------------------------------------------------------------------
|
|
9
|
+
constructor(){
|
|
10
|
+
this.entities = [];
|
|
11
|
+
this.subscribers = [];
|
|
12
|
+
}
|
|
13
|
+
// ------------------------------------------------------------------
|
|
14
|
+
buildWithEnv() {
|
|
15
|
+
const options = readDataSourceOptionsFromEnv();
|
|
16
|
+
if (!options) {
|
|
17
|
+
throw new Error('The database configuration could not be read from env variables.');
|
|
18
|
+
}
|
|
19
|
+
return this.normalize(options);
|
|
20
|
+
}
|
|
21
|
+
buildWith(options) {
|
|
22
|
+
return this.normalize(options);
|
|
23
|
+
}
|
|
24
|
+
// ------------------------------------------------------------------
|
|
25
|
+
setEntities(entities) {
|
|
26
|
+
this.entities = entities;
|
|
27
|
+
}
|
|
28
|
+
setSubscribers(subscribers) {
|
|
29
|
+
this.subscribers = subscribers;
|
|
30
|
+
}
|
|
31
|
+
// ------------------------------------------------------------------
|
|
32
|
+
normalize(options) {
|
|
33
|
+
if (options.type !== 'mysql' && options.type !== 'postgres' && options.type !== 'better-sqlite3') {
|
|
34
|
+
throw new Error(`The database type ${options.type} is not supported.`);
|
|
35
|
+
}
|
|
36
|
+
options = {
|
|
37
|
+
...options,
|
|
38
|
+
logging: false,
|
|
39
|
+
entities: [
|
|
40
|
+
...options.entities ? options.entities : [],
|
|
41
|
+
...this.entities
|
|
42
|
+
],
|
|
43
|
+
migrations: [],
|
|
44
|
+
migrationsTransactionMode: 'each',
|
|
45
|
+
subscribers: [
|
|
46
|
+
...options.subscribers || [],
|
|
47
|
+
...this.subscribers
|
|
48
|
+
]
|
|
49
|
+
};
|
|
50
|
+
if (options.type === 'mysql' || options.type === 'postgres') {
|
|
51
|
+
let migrationPath = `src/database/migrations/${options.type}/*.{ts,js}`;
|
|
52
|
+
if (!isCodeTransformation(CodeTransformation.JUST_IN_TIME)) {
|
|
53
|
+
migrationPath = transformFilePath(migrationPath, './dist', './src');
|
|
54
|
+
}
|
|
55
|
+
Object.assign(options, {
|
|
56
|
+
migrations: [
|
|
57
|
+
migrationPath
|
|
58
|
+
],
|
|
59
|
+
migrationsTransactionMode: 'all'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (options.type === 'mysql') {
|
|
63
|
+
Object.assign(options, {
|
|
64
|
+
connectorPackage: 'mysql2'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return options;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
3
70
|
|
|
4
71
|
class BaseSubscriber {
|
|
5
72
|
publisher;
|
|
@@ -7,7 +74,9 @@ class BaseSubscriber {
|
|
|
7
74
|
refType;
|
|
8
75
|
constructor(ctx){
|
|
9
76
|
this.refType = ctx.refType;
|
|
10
|
-
|
|
77
|
+
if (isEntityEventPublisherUsable()) {
|
|
78
|
+
this.publisher = useEntityEventPublisher();
|
|
79
|
+
}
|
|
11
80
|
this.destinations = ctx.destinations;
|
|
12
81
|
}
|
|
13
82
|
async afterInsert(event) {
|
|
@@ -35,6 +104,9 @@ class BaseSubscriber {
|
|
|
35
104
|
}
|
|
36
105
|
}
|
|
37
106
|
async publish(payload) {
|
|
107
|
+
if (!this.publisher) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
38
110
|
await this.publisher.safePublish({
|
|
39
111
|
data: payload.data,
|
|
40
112
|
dataPrevious: payload.dataPrevious,
|
|
@@ -49,5 +121,5 @@ class BaseSubscriber {
|
|
|
49
121
|
}
|
|
50
122
|
}
|
|
51
123
|
|
|
52
|
-
export { BaseSubscriber };
|
|
124
|
+
export { BaseSubscriber, DataSourceOptionsBuilder };
|
|
53
125
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/subscriber/base.ts"],"sourcesContent":["/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { ObjectLiteral } from '@privateaim/kit';\nimport { DomainEventName } from '@privateaim/kit';\nimport type {\n EntityEventDestinations, EntityEventDestinationsFn,\n EntityEventPublisher,\n} from '@privateaim/server-kit';\nimport { useEntityEventPublisher } from '@privateaim/server-kit';\nimport type {\n EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent,\n} from 'typeorm';\nimport type { BaseSubscriberContext, SubscriberPublishPayload } from './types';\n\nexport class BaseSubscriber<\n RECORD extends ObjectLiteral,\n> implements EntitySubscriberInterface<RECORD> {\n private readonly publisher: EntityEventPublisher;\n\n private readonly destinations : EntityEventDestinations | EntityEventDestinationsFn<RECORD>;\n\n private readonly refType: string;\n\n constructor(ctx: BaseSubscriberContext<RECORD>) {\n this.refType = ctx.refType;\n this.publisher = useEntityEventPublisher();\n this.destinations = ctx.destinations;\n }\n\n async afterInsert(event: InsertEvent<RECORD>): Promise<any> {\n await this.publish({\n data: event.entity,\n type: DomainEventName.CREATED,\n metadata: event.queryRunner.data,\n });\n }\n\n async afterUpdate(event: UpdateEvent<RECORD>): Promise<any> {\n await this.publish({\n type: DomainEventName.UPDATED,\n data: event.entity as RECORD,\n dataPrevious: event.databaseEntity,\n metadata: event.queryRunner.data,\n });\n }\n\n async beforeRemove(event: RemoveEvent<RECORD>): Promise<any> {\n if (event.entity) {\n await this.publish({\n type: DomainEventName.DELETED,\n data: event.entity as RECORD,\n metadata: event.queryRunner.data,\n });\n }\n }\n\n async publish(payload: SubscriberPublishPayload<RECORD>) {\n await this.publisher.safePublish({\n data: payload.data,\n dataPrevious: payload.dataPrevious,\n metadata: {\n ref_type: this.refType,\n ref_id: payload.data.id,\n\n event: payload.type,\n ...(payload.metadata ? payload.metadata : {}),\n },\n destinations: this.destinations,\n });\n }\n}\n"],"names":["BaseSubscriber","publisher","destinations","refType","ctx","useEntityEventPublisher","afterInsert","event","publish","data","entity","type","DomainEventName","CREATED","metadata","queryRunner","afterUpdate","UPDATED","dataPrevious","databaseEntity","beforeRemove","DELETED","payload","safePublish","ref_type","ref_id","id"],"mappings":";;;AAmBO,MAAMA,cAAAA,CAAAA;IAGQC,SAAAA;IAEAC,YAAAA;IAEAC,OAAAA;AAEjB,IAAA,WAAA,CAAYC,GAAkC,CAAE;AAC5C,QAAA,IAAI,CAACD,OAAO,GAAGC,GAAAA,CAAID,OAAO;QAC1B,IAAI,CAACF,SAAS,GAAGI,uBAAAA,EAAAA;AACjB,QAAA,IAAI,CAACH,YAAY,GAAGE,GAAAA,CAAIF,YAAY;AACxC,IAAA;IAEA,MAAMI,WAAAA,CAAYC,KAA0B,EAAgB;QACxD,MAAM,IAAI,CAACC,OAAO,CAAC;AACfC,YAAAA,IAAAA,EAAMF,MAAMG,MAAM;AAClBC,YAAAA,IAAAA,EAAMC,gBAAgBC,OAAO;YAC7BC,QAAAA,EAAUP,KAAAA,CAAMQ,WAAW,CAACN;AAChC,SAAA,CAAA;AACJ,IAAA;IAEA,MAAMO,WAAAA,CAAYT,KAA0B,EAAgB;QACxD,MAAM,IAAI,CAACC,OAAO,CAAC;AACfG,YAAAA,IAAAA,EAAMC,gBAAgBK,OAAO;AAC7BR,YAAAA,IAAAA,EAAMF,MAAMG,MAAM;AAClBQ,YAAAA,YAAAA,EAAcX,MAAMY,cAAc;YAClCL,QAAAA,EAAUP,KAAAA,CAAMQ,WAAW,CAACN;AAChC,SAAA,CAAA;AACJ,IAAA;IAEA,MAAMW,YAAAA,CAAab,KAA0B,EAAgB;QACzD,IAAIA,KAAAA,CAAMG,MAAM,EAAE;YACd,MAAM,IAAI,CAACF,OAAO,CAAC;AACfG,gBAAAA,IAAAA,EAAMC,gBAAgBS,OAAO;AAC7BZ,gBAAAA,IAAAA,EAAMF,MAAMG,MAAM;gBAClBI,QAAAA,EAAUP,KAAAA,CAAMQ,WAAW,CAACN;AAChC,aAAA,CAAA;AACJ,QAAA;AACJ,IAAA;IAEA,MAAMD,OAAAA,CAAQc,OAAyC,EAAE;AACrD,QAAA,MAAM,IAAI,CAACrB,SAAS,CAACsB,WAAW,CAAC;AAC7Bd,YAAAA,IAAAA,EAAMa,QAAQb,IAAI;AAClBS,YAAAA,YAAAA,EAAcI,QAAQJ,YAAY;YAClCJ,QAAAA,EAAU;gBACNU,QAAAA,EAAU,IAAI,CAACrB,OAAO;gBACtBsB,MAAAA,EAAQH,OAAAA,CAAQb,IAAI,CAACiB,EAAE;AAEvBnB,gBAAAA,KAAAA,EAAOe,QAAQX,IAAI;AACnB,gBAAA,GAAIW,QAAQR,QAAQ,GAAGQ,QAAQR,QAAQ,GAAG;AAC9C,aAAA;YACAZ,YAAAA,EAAc,IAAI,CAACA;AACvB,SAAA,CAAA;AACJ,IAAA;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/data-source/options.ts","../src/subscriber/base.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { DataSourceOptions } from 'typeorm';\nimport {\n CodeTransformation,\n isCodeTransformation,\n readDataSourceOptionsFromEnv,\n transformFilePath,\n} from 'typeorm-extension';\n\nexport type DataSourceOptionsEntities = DataSourceOptions['entities'];\nexport type DataSourceOptionsSubscribers = DataSourceOptions['subscribers'];\n\nexport class DataSourceOptionsBuilder {\n protected entities : DataSourceOptionsEntities;\n\n protected subscribers : DataSourceOptionsSubscribers;\n\n // ------------------------------------------------------------------\n\n constructor() {\n this.entities = [];\n this.subscribers = [];\n }\n\n // ------------------------------------------------------------------\n\n buildWithEnv() {\n const options = readDataSourceOptionsFromEnv();\n\n if (!options) {\n throw new Error('The database configuration could not be read from env variables.');\n }\n\n return this.normalize(options);\n }\n\n buildWith(options: DataSourceOptions) {\n return this.normalize(options);\n }\n\n // ------------------------------------------------------------------\n\n setEntities(entities: DataSourceOptionsEntities) {\n this.entities = entities;\n }\n\n setSubscribers(subscribers: DataSourceOptionsSubscribers) {\n this.subscribers = subscribers;\n }\n\n // ------------------------------------------------------------------\n\n protected normalize(options: DataSourceOptions) : DataSourceOptions {\n if (\n options.type !== 'mysql' &&\n options.type !== 'postgres' &&\n options.type !== 'better-sqlite3'\n ) {\n throw new Error(`The database type ${options.type} is not supported.`);\n }\n\n options = {\n ...options,\n logging: false,\n entities: [\n ...(options.entities ? options.entities : []) as string[],\n ...(this.entities) as string[],\n ],\n migrations: [],\n migrationsTransactionMode: 'each',\n subscribers: [\n ...(options.subscribers || []) as string[],\n ...this.subscribers as string[],\n ],\n };\n\n if (options.type === 'mysql' || options.type === 'postgres') {\n let migrationPath = `src/database/migrations/${options.type}/*.{ts,js}`;\n if (!isCodeTransformation(CodeTransformation.JUST_IN_TIME)) {\n migrationPath = transformFilePath(migrationPath, './dist', './src');\n }\n\n Object.assign(options, {\n migrations: [migrationPath],\n migrationsTransactionMode: 'all',\n } as DataSourceOptions);\n }\n\n if (options.type === 'mysql') {\n Object.assign(options, {\n connectorPackage: 'mysql2',\n } satisfies Partial<DataSourceOptions>);\n }\n\n return options;\n }\n}\n","/*\n * Copyright (c) 2025.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { ObjectLiteral } from '@privateaim/kit';\nimport { DomainEventName } from '@privateaim/kit';\nimport type {\n EntityEventDestinations, EntityEventDestinationsFn,\n EntityEventPublisher,\n} from '@privateaim/server-kit';\nimport {\n isEntityEventPublisherUsable,\n useEntityEventPublisher,\n} from '@privateaim/server-kit';\nimport type {\n EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent,\n} from 'typeorm';\nimport type { BaseSubscriberContext, SubscriberPublishPayload } from './types';\n\nexport class BaseSubscriber<\n RECORD extends ObjectLiteral,\n> implements EntitySubscriberInterface<RECORD> {\n private readonly publisher: EntityEventPublisher | undefined;\n\n private readonly destinations : EntityEventDestinations | EntityEventDestinationsFn<RECORD>;\n\n private readonly refType: string;\n\n constructor(ctx: BaseSubscriberContext<RECORD>) {\n this.refType = ctx.refType;\n if (isEntityEventPublisherUsable()) {\n this.publisher = useEntityEventPublisher();\n }\n\n this.destinations = ctx.destinations;\n }\n\n async afterInsert(event: InsertEvent<RECORD>): Promise<any> {\n await this.publish({\n data: event.entity,\n type: DomainEventName.CREATED,\n metadata: event.queryRunner.data,\n });\n }\n\n async afterUpdate(event: UpdateEvent<RECORD>): Promise<any> {\n await this.publish({\n type: DomainEventName.UPDATED,\n data: event.entity as RECORD,\n dataPrevious: event.databaseEntity,\n metadata: event.queryRunner.data,\n });\n }\n\n async beforeRemove(event: RemoveEvent<RECORD>): Promise<any> {\n if (event.entity) {\n await this.publish({\n type: DomainEventName.DELETED,\n data: event.entity as RECORD,\n metadata: event.queryRunner.data,\n });\n }\n }\n\n async publish(payload: SubscriberPublishPayload<RECORD>) {\n if (!this.publisher) {\n return;\n }\n\n await this.publisher.safePublish({\n data: payload.data,\n dataPrevious: payload.dataPrevious,\n metadata: {\n ref_type: this.refType,\n ref_id: payload.data.id,\n\n event: payload.type,\n ...(payload.metadata ? payload.metadata : {}),\n },\n destinations: this.destinations,\n });\n }\n}\n"],"names":["DataSourceOptionsBuilder","entities","subscribers","buildWithEnv","options","readDataSourceOptionsFromEnv","Error","normalize","buildWith","setEntities","setSubscribers","type","logging","migrations","migrationsTransactionMode","migrationPath","isCodeTransformation","CodeTransformation","JUST_IN_TIME","transformFilePath","Object","assign","connectorPackage","BaseSubscriber","publisher","destinations","refType","ctx","isEntityEventPublisherUsable","useEntityEventPublisher","afterInsert","event","publish","data","entity","DomainEventName","CREATED","metadata","queryRunner","afterUpdate","UPDATED","dataPrevious","databaseEntity","beforeRemove","DELETED","payload","safePublish","ref_type","ref_id","id"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/subscriber/base.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/subscriber/base.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAUrD,OAAO,KAAK,EACR,yBAAyB,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EACnE,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAE/E,qBAAa,cAAc,CACvB,MAAM,SAAS,aAAa,CAC9B,YAAW,yBAAyB,CAAC,MAAM,CAAC;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAE7D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+D;IAE5F,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,GAAG,EAAE,qBAAqB,CAAC,MAAM,CAAC;IASxC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAQrD,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IASrD,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAUtD,OAAO,CAAC,OAAO,EAAE,wBAAwB,CAAC,MAAM,CAAC;CAkB1D"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@privateaim/server-db-kit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.28",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -19,16 +19,16 @@
|
|
|
19
19
|
"license": "Apache-2.0",
|
|
20
20
|
"description": "This package contains server side db helpers & utilities.",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@privateaim/kit": "^0.8.
|
|
23
|
-
"@privateaim/server-kit": "^0.8.
|
|
22
|
+
"@privateaim/kit": "^0.8.28",
|
|
23
|
+
"@privateaim/server-kit": "^0.8.28"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"typeorm": "^0.3.28",
|
|
27
|
-
"typeorm-extension": "^3.
|
|
27
|
+
"typeorm-extension": "^3.9.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"typeorm": "^0.3.28",
|
|
31
|
-
"typeorm-extension": "^3.
|
|
31
|
+
"typeorm-extension": "^3.9.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build:types": "tsc --emitDeclarationOnly -p tsconfig.build.json",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026.
|
|
3
|
+
* Author Peter Placzek (tada5hi)
|
|
4
|
+
* For the full copyright and license information,
|
|
5
|
+
* view the LICENSE file that was distributed with this source code.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { DataSourceOptions } from 'typeorm';
|
|
9
|
+
import {
|
|
10
|
+
CodeTransformation,
|
|
11
|
+
isCodeTransformation,
|
|
12
|
+
readDataSourceOptionsFromEnv,
|
|
13
|
+
transformFilePath,
|
|
14
|
+
} from 'typeorm-extension';
|
|
15
|
+
|
|
16
|
+
export type DataSourceOptionsEntities = DataSourceOptions['entities'];
|
|
17
|
+
export type DataSourceOptionsSubscribers = DataSourceOptions['subscribers'];
|
|
18
|
+
|
|
19
|
+
export class DataSourceOptionsBuilder {
|
|
20
|
+
protected entities : DataSourceOptionsEntities;
|
|
21
|
+
|
|
22
|
+
protected subscribers : DataSourceOptionsSubscribers;
|
|
23
|
+
|
|
24
|
+
// ------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
this.entities = [];
|
|
28
|
+
this.subscribers = [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
buildWithEnv() {
|
|
34
|
+
const options = readDataSourceOptionsFromEnv();
|
|
35
|
+
|
|
36
|
+
if (!options) {
|
|
37
|
+
throw new Error('The database configuration could not be read from env variables.');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this.normalize(options);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
buildWith(options: DataSourceOptions) {
|
|
44
|
+
return this.normalize(options);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
setEntities(entities: DataSourceOptionsEntities) {
|
|
50
|
+
this.entities = entities;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setSubscribers(subscribers: DataSourceOptionsSubscribers) {
|
|
54
|
+
this.subscribers = subscribers;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
protected normalize(options: DataSourceOptions) : DataSourceOptions {
|
|
60
|
+
if (
|
|
61
|
+
options.type !== 'mysql' &&
|
|
62
|
+
options.type !== 'postgres' &&
|
|
63
|
+
options.type !== 'better-sqlite3'
|
|
64
|
+
) {
|
|
65
|
+
throw new Error(`The database type ${options.type} is not supported.`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
options = {
|
|
69
|
+
...options,
|
|
70
|
+
logging: false,
|
|
71
|
+
entities: [
|
|
72
|
+
...(options.entities ? options.entities : []) as string[],
|
|
73
|
+
...(this.entities) as string[],
|
|
74
|
+
],
|
|
75
|
+
migrations: [],
|
|
76
|
+
migrationsTransactionMode: 'each',
|
|
77
|
+
subscribers: [
|
|
78
|
+
...(options.subscribers || []) as string[],
|
|
79
|
+
...this.subscribers as string[],
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
if (options.type === 'mysql' || options.type === 'postgres') {
|
|
84
|
+
let migrationPath = `src/database/migrations/${options.type}/*.{ts,js}`;
|
|
85
|
+
if (!isCodeTransformation(CodeTransformation.JUST_IN_TIME)) {
|
|
86
|
+
migrationPath = transformFilePath(migrationPath, './dist', './src');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
Object.assign(options, {
|
|
90
|
+
migrations: [migrationPath],
|
|
91
|
+
migrationsTransactionMode: 'all',
|
|
92
|
+
} as DataSourceOptions);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (options.type === 'mysql') {
|
|
96
|
+
Object.assign(options, {
|
|
97
|
+
connectorPackage: 'mysql2',
|
|
98
|
+
} satisfies Partial<DataSourceOptions>);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return options;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/src/index.ts
CHANGED
package/src/subscriber/base.ts
CHANGED
|
@@ -11,7 +11,10 @@ import type {
|
|
|
11
11
|
EntityEventDestinations, EntityEventDestinationsFn,
|
|
12
12
|
EntityEventPublisher,
|
|
13
13
|
} from '@privateaim/server-kit';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
isEntityEventPublisherUsable,
|
|
16
|
+
useEntityEventPublisher,
|
|
17
|
+
} from '@privateaim/server-kit';
|
|
15
18
|
import type {
|
|
16
19
|
EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent,
|
|
17
20
|
} from 'typeorm';
|
|
@@ -20,7 +23,7 @@ import type { BaseSubscriberContext, SubscriberPublishPayload } from './types';
|
|
|
20
23
|
export class BaseSubscriber<
|
|
21
24
|
RECORD extends ObjectLiteral,
|
|
22
25
|
> implements EntitySubscriberInterface<RECORD> {
|
|
23
|
-
private readonly publisher: EntityEventPublisher;
|
|
26
|
+
private readonly publisher: EntityEventPublisher | undefined;
|
|
24
27
|
|
|
25
28
|
private readonly destinations : EntityEventDestinations | EntityEventDestinationsFn<RECORD>;
|
|
26
29
|
|
|
@@ -28,7 +31,10 @@ export class BaseSubscriber<
|
|
|
28
31
|
|
|
29
32
|
constructor(ctx: BaseSubscriberContext<RECORD>) {
|
|
30
33
|
this.refType = ctx.refType;
|
|
31
|
-
|
|
34
|
+
if (isEntityEventPublisherUsable()) {
|
|
35
|
+
this.publisher = useEntityEventPublisher();
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
this.destinations = ctx.destinations;
|
|
33
39
|
}
|
|
34
40
|
|
|
@@ -60,6 +66,10 @@ export class BaseSubscriber<
|
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
async publish(payload: SubscriberPublishPayload<RECORD>) {
|
|
69
|
+
if (!this.publisher) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
63
73
|
await this.publisher.safePublish({
|
|
64
74
|
data: payload.data,
|
|
65
75
|
dataPrevious: payload.dataPrevious,
|