@dbos-inc/typeorm-datasource 5.2.8-preview → 5.2.9-preview
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 +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -26
- package/dist/index.js.map +1 -1
- package/index.ts +43 -32
- package/package.json +1 -1
- package/tests/datasource.test.ts +48 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PoolConfig } from 'pg';
|
|
2
2
|
import { FunctionName } from '@dbos-inc/dbos-sdk';
|
|
3
|
-
import { DBOSDataSource, PGTransactionConfig } from '@dbos-inc/dbos-sdk/datasource';
|
|
3
|
+
import { DBOSDataSource, PGTransactionConfig, DataSourceMigrationOptions } from '@dbos-inc/dbos-sdk/datasource';
|
|
4
4
|
import { DataSource, EntityManager } from 'typeorm';
|
|
5
5
|
export interface TypeORMTransactionConfig extends PGTransactionConfig {
|
|
6
6
|
name?: string;
|
|
@@ -10,10 +10,16 @@ export declare class TypeOrmDataSource implements DBOSDataSource<TypeORMTransact
|
|
|
10
10
|
readonly name: string;
|
|
11
11
|
static get entityManager(): EntityManager;
|
|
12
12
|
get entityManager(): EntityManager;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Create or migrate the DBOS transaction schema, typically with a privileged role,
|
|
15
|
+
* optionally granting `applicationRole` the minimal permissions to use it.
|
|
16
|
+
*/
|
|
17
|
+
static initializeDBOSSchema(config: PoolConfig, schemaName?: string, options?: {
|
|
18
|
+
applicationRole?: string;
|
|
19
|
+
}): Promise<void>;
|
|
14
20
|
private constructor();
|
|
15
|
-
static createFromConfig(name: string, config: PoolConfig, entities: Function[], schemaName?: string): TypeOrmDataSource;
|
|
16
|
-
static createFromDataSource(name: string, ds: DataSource, schemaName?: string): TypeOrmDataSource;
|
|
21
|
+
static createFromConfig(name: string, config: PoolConfig, entities: Function[], schemaName?: string, options?: DataSourceMigrationOptions): TypeOrmDataSource;
|
|
22
|
+
static createFromDataSource(name: string, ds: DataSource, schemaName?: string, options?: DataSourceMigrationOptions): TypeOrmDataSource;
|
|
17
23
|
/**
|
|
18
24
|
* Run `func` as a transaction against this DataSource
|
|
19
25
|
* @param func Function to run within a transactional context
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAQ,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAQ,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAUL,cAAc,EAEd,mBAAmB,EACnB,0BAA0B,EAK3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAKpD,MAAM,WAAW,wBAAyB,SAAQ,mBAAmB;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAgQD,qBAAa,iBAAkB,YAAW,cAAc,CAAC,wBAAwB,CAAC;;IA+C9E,QAAQ,CAAC,IAAI,EAAE,MAAM;IA9BvB,MAAM,KAAK,aAAa,kBAEvB;IAED,IAAI,aAAa,kBAEhB;IAED;;;OAGG;WACU,oBAAoB,CAC/B,MAAM,EAAE,UAAU,EAClB,UAAU,GAAE,MAAe,EAC3B,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,IAAI,CAAC;IAahB,OAAO;IAsBP,MAAM,CAAC,gBAAgB,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAElB,QAAQ,EAAE,QAAQ,EAAE,EACpB,UAAU,GAAE,MAAe,EAC3B,OAAO,GAAE,0BAA+B;IAK1C,MAAM,CAAC,oBAAoB,CACzB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,UAAU,EACd,UAAU,GAAE,MAAe,EAC3B,OAAO,GAAE,0BAA+B;IAK1C;;;;;;OAMG;IACG,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,wBAAwB;IAIjF;;;;;;;;OAQG;IACH,mBAAmB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EACpD,MAAM,CAAC,EAAE,wBAAwB,GAAG,YAAY,GAC/C,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD;;OAEG;IACH,WAAW,CAAC,MAAM,CAAC,EAAE,wBAAwB,kDAIjC,MAAM,eACD,WAAW,cACZ,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,oCAAxC,IAAI,WAAW,IAAI,KAAK,QAAQ,MAAM,CAAC;CAevF"}
|
package/dist/index.js
CHANGED
|
@@ -7,20 +7,25 @@ const typeorm_1 = require("typeorm");
|
|
|
7
7
|
const async_hooks_1 = require("async_hooks");
|
|
8
8
|
const superjson_1 = require("superjson");
|
|
9
9
|
const asyncLocalCtx = new async_hooks_1.AsyncLocalStorage();
|
|
10
|
+
function typeOrmExecutor(db) {
|
|
11
|
+
return async (sql) => await db.query(sql);
|
|
12
|
+
}
|
|
10
13
|
class TypeOrmTransactionHandler {
|
|
11
14
|
name;
|
|
12
15
|
config;
|
|
13
16
|
entities;
|
|
14
17
|
providedDataSource;
|
|
18
|
+
options;
|
|
15
19
|
#createdDataSource;
|
|
16
20
|
schemaName;
|
|
17
21
|
constructor(name, config,
|
|
18
22
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
19
|
-
entities, providedDataSource, schemaName = 'dbos') {
|
|
23
|
+
entities, providedDataSource, schemaName = 'dbos', options = {}) {
|
|
20
24
|
this.name = name;
|
|
21
25
|
this.config = config;
|
|
22
26
|
this.entities = entities;
|
|
23
27
|
this.providedDataSource = providedDataSource;
|
|
28
|
+
this.options = options;
|
|
24
29
|
this.schemaName = schemaName;
|
|
25
30
|
}
|
|
26
31
|
static async createDataSource(config,
|
|
@@ -56,24 +61,16 @@ class TypeOrmTransactionHandler {
|
|
|
56
61
|
this.#createdDataSource = await TypeOrmTransactionHandler.createDataSource(this.config, this.entities);
|
|
57
62
|
await ds?.destroy();
|
|
58
63
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
installed = !!res[0]?.schema_exists && !!res[0]?.table_exists;
|
|
64
|
+
if (this.options.runMigrations === false) {
|
|
65
|
+
await (0, datasource_1.verifyDataSourcePG)(typeOrmExecutor(this.dataSource), this.schemaName, this.name);
|
|
66
|
+
return;
|
|
63
67
|
}
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
try {
|
|
69
|
+
await this.dataSource.transaction((em) => (0, datasource_1.migrateDataSourcePG)(typeOrmExecutor(em), this.schemaName));
|
|
66
70
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
await this.dataSource.query((0, datasource_1.createTransactionCompletionSchemaPG)(this.schemaName));
|
|
71
|
-
await this.dataSource.query((0, datasource_1.createTransactionCompletionTablePG)(this.schemaName));
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
throw new Error(`In initialization of 'TypeOrmDataSource' ${this.name}: The '${this.schemaName}.transaction_completion' table does not exist, and could not be created. This should be added to your database migrations.
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw new Error(`In initialization of 'TypeOrmDataSource' ${this.name}: The '${this.schemaName}' transaction schema could not be migrated: ${err.message}. This should be added to your database migrations.
|
|
75
73
|
See: https://docs.dbos.dev/typescript/tutorials/transaction-tutorial#installing-the-dbos-schema`);
|
|
76
|
-
}
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
76
|
async destroy() {
|
|
@@ -216,11 +213,14 @@ class TypeOrmDataSource {
|
|
|
216
213
|
get entityManager() {
|
|
217
214
|
return TypeOrmDataSource.#getEntityManager(this.#provider);
|
|
218
215
|
}
|
|
219
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Create or migrate the DBOS transaction schema, typically with a privileged role,
|
|
218
|
+
* optionally granting `applicationRole` the minimal permissions to use it.
|
|
219
|
+
*/
|
|
220
|
+
static async initializeDBOSSchema(config, schemaName = 'dbos', options = {}) {
|
|
220
221
|
const ds = await TypeOrmTransactionHandler.createDataSource(config, []);
|
|
221
222
|
try {
|
|
222
|
-
await ds.
|
|
223
|
-
await ds.query((0, datasource_1.createTransactionCompletionTablePG)(schemaName));
|
|
223
|
+
await ds.transaction((em) => (0, datasource_1.initializeDataSourceSchemaPG)(typeOrmExecutor(em), schemaName, options.applicationRole));
|
|
224
224
|
}
|
|
225
225
|
finally {
|
|
226
226
|
await ds.destroy();
|
|
@@ -229,14 +229,14 @@ class TypeOrmDataSource {
|
|
|
229
229
|
#provider;
|
|
230
230
|
constructor(name, config,
|
|
231
231
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
232
|
-
entities, dataSource, schemaName = 'dbos') {
|
|
232
|
+
entities, dataSource, schemaName = 'dbos', options = {}) {
|
|
233
233
|
this.name = name;
|
|
234
234
|
if (config && entities) {
|
|
235
|
-
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined, schemaName);
|
|
235
|
+
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined, schemaName, options);
|
|
236
236
|
(0, datasource_1.registerDataSource)(this.#provider);
|
|
237
237
|
}
|
|
238
238
|
else if (dataSource) {
|
|
239
|
-
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource, schemaName);
|
|
239
|
+
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource, schemaName, options);
|
|
240
240
|
(0, datasource_1.registerDataSource)(this.#provider);
|
|
241
241
|
}
|
|
242
242
|
else {
|
|
@@ -245,11 +245,11 @@ class TypeOrmDataSource {
|
|
|
245
245
|
}
|
|
246
246
|
static createFromConfig(name, config,
|
|
247
247
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
248
|
-
entities, schemaName = 'dbos') {
|
|
249
|
-
return new TypeOrmDataSource(name, config, entities, undefined, schemaName);
|
|
248
|
+
entities, schemaName = 'dbos', options = {}) {
|
|
249
|
+
return new TypeOrmDataSource(name, config, entities, undefined, schemaName, options);
|
|
250
250
|
}
|
|
251
|
-
static createFromDataSource(name, ds, schemaName = 'dbos') {
|
|
252
|
-
return new TypeOrmDataSource(name, undefined, undefined, ds, schemaName);
|
|
251
|
+
static createFromDataSource(name, ds, schemaName = 'dbos', options = {}) {
|
|
252
|
+
return new TypeOrmDataSource(name, undefined, undefined, ds, schemaName, options);
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
255
255
|
* Run `func` as a transaction against this DataSource
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AACA,iDAAwD;AACxD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/index.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { PoolConfig } from 'pg';
|
|
|
2
2
|
import { DBOS, FunctionName } from '@dbos-inc/dbos-sdk';
|
|
3
3
|
import {
|
|
4
4
|
type DataSourceTransactionHandler,
|
|
5
|
-
createTransactionCompletionSchemaPG,
|
|
6
|
-
createTransactionCompletionTablePG,
|
|
7
5
|
isPGRetriableTransactionError,
|
|
8
6
|
DBOSError,
|
|
9
7
|
DBOSStepAlreadyRecordedError,
|
|
@@ -15,8 +13,11 @@ import {
|
|
|
15
13
|
DBOSDataSource,
|
|
16
14
|
registerDataSource,
|
|
17
15
|
PGTransactionConfig,
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
DataSourceMigrationOptions,
|
|
17
|
+
DataSourceSQLExecutor,
|
|
18
|
+
initializeDataSourceSchemaPG,
|
|
19
|
+
migrateDataSourcePG,
|
|
20
|
+
verifyDataSourcePG,
|
|
20
21
|
} from '@dbos-inc/dbos-sdk/datasource';
|
|
21
22
|
import { DataSource, EntityManager } from 'typeorm';
|
|
22
23
|
import type { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
|
|
@@ -34,6 +35,10 @@ interface DBOSTypeOrmLocalCtx {
|
|
|
34
35
|
|
|
35
36
|
const asyncLocalCtx = new AsyncLocalStorage<DBOSTypeOrmLocalCtx>();
|
|
36
37
|
|
|
38
|
+
function typeOrmExecutor(db: DataSource | EntityManager): DataSourceSQLExecutor {
|
|
39
|
+
return async (sql) => await db.query<Record<string, unknown>[]>(sql);
|
|
40
|
+
}
|
|
41
|
+
|
|
37
42
|
interface transaction_completion {
|
|
38
43
|
workflow_id: string;
|
|
39
44
|
function_num: number;
|
|
@@ -52,6 +57,7 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
52
57
|
private readonly entities?: Function[],
|
|
53
58
|
private readonly providedDataSource?: DataSource,
|
|
54
59
|
schemaName: string = 'dbos',
|
|
60
|
+
private readonly options: DataSourceMigrationOptions = {},
|
|
55
61
|
) {
|
|
56
62
|
this.schemaName = schemaName;
|
|
57
63
|
}
|
|
@@ -94,29 +100,18 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
94
100
|
await ds?.destroy();
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
checkSchemaInstallationPG(this.schemaName),
|
|
101
|
-
);
|
|
102
|
-
installed = !!res[0]?.schema_exists && !!res[0]?.table_exists;
|
|
103
|
-
} catch (e) {
|
|
104
|
-
throw new Error(
|
|
105
|
-
`In initialization of 'TypeOrmDataSource' ${this.name}: Database could not be reached: ${(e as Error).message}`,
|
|
106
|
-
);
|
|
103
|
+
if (this.options.runMigrations === false) {
|
|
104
|
+
await verifyDataSourcePG(typeOrmExecutor(this.dataSource), this.schemaName, this.name);
|
|
105
|
+
return;
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
} catch (err) {
|
|
115
|
-
throw new Error(
|
|
116
|
-
`In initialization of 'TypeOrmDataSource' ${this.name}: The '${this.schemaName}.transaction_completion' table does not exist, and could not be created. This should be added to your database migrations.
|
|
108
|
+
try {
|
|
109
|
+
await this.dataSource.transaction((em) => migrateDataSourcePG(typeOrmExecutor(em), this.schemaName));
|
|
110
|
+
} catch (err) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`In initialization of 'TypeOrmDataSource' ${this.name}: The '${this.schemaName}' transaction schema could not be migrated: ${(err as Error).message}. This should be added to your database migrations.
|
|
117
113
|
See: https://docs.dbos.dev/typescript/tutorials/transaction-tutorial#installing-the-dbos-schema`,
|
|
118
|
-
|
|
119
|
-
}
|
|
114
|
+
);
|
|
120
115
|
}
|
|
121
116
|
}
|
|
122
117
|
|
|
@@ -312,11 +307,20 @@ export class TypeOrmDataSource implements DBOSDataSource<TypeORMTransactionConfi
|
|
|
312
307
|
return TypeOrmDataSource.#getEntityManager(this.#provider);
|
|
313
308
|
}
|
|
314
309
|
|
|
315
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Create or migrate the DBOS transaction schema, typically with a privileged role,
|
|
312
|
+
* optionally granting `applicationRole` the minimal permissions to use it.
|
|
313
|
+
*/
|
|
314
|
+
static async initializeDBOSSchema(
|
|
315
|
+
config: PoolConfig,
|
|
316
|
+
schemaName: string = 'dbos',
|
|
317
|
+
options: { applicationRole?: string } = {},
|
|
318
|
+
): Promise<void> {
|
|
316
319
|
const ds = await TypeOrmTransactionHandler.createDataSource(config, []);
|
|
317
320
|
try {
|
|
318
|
-
await ds.
|
|
319
|
-
|
|
321
|
+
await ds.transaction((em) =>
|
|
322
|
+
initializeDataSourceSchemaPG(typeOrmExecutor(em), schemaName, options.applicationRole),
|
|
323
|
+
);
|
|
320
324
|
} finally {
|
|
321
325
|
await ds.destroy();
|
|
322
326
|
}
|
|
@@ -331,12 +335,13 @@ export class TypeOrmDataSource implements DBOSDataSource<TypeORMTransactionConfi
|
|
|
331
335
|
entities?: Function[],
|
|
332
336
|
dataSource?: DataSource,
|
|
333
337
|
schemaName: string = 'dbos',
|
|
338
|
+
options: DataSourceMigrationOptions = {},
|
|
334
339
|
) {
|
|
335
340
|
if (config && entities) {
|
|
336
|
-
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined, schemaName);
|
|
341
|
+
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined, schemaName, options);
|
|
337
342
|
registerDataSource(this.#provider);
|
|
338
343
|
} else if (dataSource) {
|
|
339
|
-
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource, schemaName);
|
|
344
|
+
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource, schemaName, options);
|
|
340
345
|
registerDataSource(this.#provider);
|
|
341
346
|
} else {
|
|
342
347
|
throw new TypeError(
|
|
@@ -351,12 +356,18 @@ export class TypeOrmDataSource implements DBOSDataSource<TypeORMTransactionConfi
|
|
|
351
356
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
352
357
|
entities: Function[],
|
|
353
358
|
schemaName: string = 'dbos',
|
|
359
|
+
options: DataSourceMigrationOptions = {},
|
|
354
360
|
) {
|
|
355
|
-
return new TypeOrmDataSource(name, config, entities, undefined, schemaName);
|
|
361
|
+
return new TypeOrmDataSource(name, config, entities, undefined, schemaName, options);
|
|
356
362
|
}
|
|
357
363
|
|
|
358
|
-
static createFromDataSource(
|
|
359
|
-
|
|
364
|
+
static createFromDataSource(
|
|
365
|
+
name: string,
|
|
366
|
+
ds: DataSource,
|
|
367
|
+
schemaName: string = 'dbos',
|
|
368
|
+
options: DataSourceMigrationOptions = {},
|
|
369
|
+
) {
|
|
370
|
+
return new TypeOrmDataSource(name, undefined, undefined, ds, schemaName, options);
|
|
360
371
|
}
|
|
361
372
|
|
|
362
373
|
/**
|
package/package.json
CHANGED
package/tests/datasource.test.ts
CHANGED
|
@@ -696,3 +696,51 @@ describe('TypeOrmDataSourceCreateTxC', () => {
|
|
|
696
696
|
expect(rows).toHaveLength(0);
|
|
697
697
|
});
|
|
698
698
|
});
|
|
699
|
+
|
|
700
|
+
describe('TypeOrmDataSource migrations', () => {
|
|
701
|
+
const userDB = new Pool(config);
|
|
702
|
+
|
|
703
|
+
afterAll(async () => {
|
|
704
|
+
await userDB.end();
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
afterEach(async () => {
|
|
708
|
+
await DBOS.shutdown();
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
test('verify-only initialization requires the schema to be migrated out of band', async () => {
|
|
712
|
+
const suffix = randomUUID().replace(/-/g, '').slice(0, 8);
|
|
713
|
+
const schemaName = `ds_mig_${suffix}`;
|
|
714
|
+
const role = `ds_app_${suffix}`;
|
|
715
|
+
const admin = new Client({ ...config, database: 'postgres' });
|
|
716
|
+
await admin.connect();
|
|
717
|
+
try {
|
|
718
|
+
await ensureDB(admin, config.database);
|
|
719
|
+
} finally {
|
|
720
|
+
await admin.end();
|
|
721
|
+
}
|
|
722
|
+
await userDB.query(`CREATE ROLE "${role}"`);
|
|
723
|
+
try {
|
|
724
|
+
TypeOrmDataSource.createFromConfig(`verify-only-${suffix}`, config, [Greeting], schemaName, {
|
|
725
|
+
runMigrations: false,
|
|
726
|
+
});
|
|
727
|
+
DBOS.setConfig({ name: 'typeorm-ds-test' });
|
|
728
|
+
await expect(DBOS.launch()).rejects.toThrow(/is at transaction schema version 0/);
|
|
729
|
+
await DBOS.shutdown();
|
|
730
|
+
const { rowCount } = await userDB.query('SELECT 1 FROM pg_namespace WHERE nspname = $1', [schemaName]);
|
|
731
|
+
expect(rowCount).toBe(0);
|
|
732
|
+
|
|
733
|
+
await TypeOrmDataSource.initializeDBOSSchema(config, schemaName, { applicationRole: role });
|
|
734
|
+
await DBOS.launch();
|
|
735
|
+
const { rows } = await userDB.query<{ allowed: boolean }>(
|
|
736
|
+
`SELECT has_table_privilege($1, $2, 'INSERT') AS allowed`,
|
|
737
|
+
[role, `"${schemaName}".transaction_completion`],
|
|
738
|
+
);
|
|
739
|
+
expect(rows).toEqual([{ allowed: true }]);
|
|
740
|
+
} finally {
|
|
741
|
+
await userDB.query(`DROP SCHEMA IF EXISTS "${schemaName}" CASCADE`);
|
|
742
|
+
await userDB.query(`DROP OWNED BY "${role}"`);
|
|
743
|
+
await userDB.query(`DROP ROLE "${role}"`);
|
|
744
|
+
}
|
|
745
|
+
});
|
|
746
|
+
});
|