@dbos-inc/koa-serve 3.0.27-preview → 3.0.29-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/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/tests/test-helpers.ts +13 -0
- package/tests/transactions.test.ts +118 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbos-inc/koa-serve",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.29-preview",
|
|
4
4
|
"description": "DBOS HTTP Package for serving workflows with Koa",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"typescript": "^5.3.3"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@dbos-inc/dbos-sdk": "*"
|
|
33
|
+
"@dbos-inc/dbos-sdk": "*",
|
|
34
|
+
"@dbos-inc/knex-datasource": "*"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@koa/bodyparser": "5.0.0",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Client } from 'pg';
|
|
2
|
+
|
|
3
|
+
export async function ensureDB(client: Client, name: string) {
|
|
4
|
+
const results = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [name]);
|
|
5
|
+
if (results.rows.length === 0) {
|
|
6
|
+
await client.query(`CREATE DATABASE ${name}`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function dropDB(client: Client, name: string, force: boolean = false) {
|
|
11
|
+
const withForce = force ? ' WITH (FORCE)' : '';
|
|
12
|
+
await client.query(`DROP DATABASE IF EXISTS ${name} ${withForce}`);
|
|
13
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { DBOS } from '@dbos-inc/dbos-sdk';
|
|
2
|
+
import { Client, Pool } from 'pg';
|
|
3
|
+
import { KnexDataSource } from '@dbos-inc/knex-datasource';
|
|
4
|
+
import { dropDB, ensureDB } from './test-helpers';
|
|
5
|
+
import Koa from 'koa';
|
|
6
|
+
import Router from '@koa/router';
|
|
7
|
+
import { DBOSKoa } from '../src';
|
|
8
|
+
|
|
9
|
+
import request from 'supertest';
|
|
10
|
+
|
|
11
|
+
const config = { client: 'pg', connection: { user: 'postgres', database: 'koa_knex_ds_test_userdb' } };
|
|
12
|
+
const knexds = new KnexDataSource('app-db', config);
|
|
13
|
+
|
|
14
|
+
const dhttp = new DBOSKoa();
|
|
15
|
+
|
|
16
|
+
interface greetings {
|
|
17
|
+
name: string;
|
|
18
|
+
greet_count: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe('KnexDataSource', () => {
|
|
22
|
+
const userDB = new Pool(config.connection);
|
|
23
|
+
let app: Koa;
|
|
24
|
+
let appRouter: Router;
|
|
25
|
+
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
{
|
|
28
|
+
const client = new Client({ ...config.connection, database: 'postgres' });
|
|
29
|
+
try {
|
|
30
|
+
await client.connect();
|
|
31
|
+
await dropDB(client, 'koa_knex_ds_test', true);
|
|
32
|
+
await dropDB(client, 'koa_knex_ds_test_dbos_sys', true);
|
|
33
|
+
await dropDB(client, config.connection.database, true);
|
|
34
|
+
await ensureDB(client, config.connection.database);
|
|
35
|
+
} finally {
|
|
36
|
+
await client.end();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
const client = await userDB.connect();
|
|
42
|
+
try {
|
|
43
|
+
await client.query(
|
|
44
|
+
'CREATE TABLE greetings(name text NOT NULL, greet_count integer DEFAULT 0, PRIMARY KEY(name))',
|
|
45
|
+
);
|
|
46
|
+
} finally {
|
|
47
|
+
client.release();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await KnexDataSource.initializeDBOSSchema(config);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
afterAll(async () => {
|
|
55
|
+
await userDB.end();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
beforeEach(async () => {
|
|
59
|
+
DBOS.setConfig({ name: 'koa-knex-ds-test' });
|
|
60
|
+
DBOS.registerLifecycleCallback(dhttp);
|
|
61
|
+
await DBOS.launch();
|
|
62
|
+
app = new Koa();
|
|
63
|
+
appRouter = new Router();
|
|
64
|
+
dhttp.registerWithApp(app, appRouter);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(async () => {
|
|
68
|
+
await DBOS.shutdown();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('use-dstx-and-koa', async () => {
|
|
72
|
+
const u1 = await KnexKoa.insertOneWay('joe');
|
|
73
|
+
expect(u1.user).toBe('joe');
|
|
74
|
+
const u2 = await KnexKoa.insertTheOtherWay('jack');
|
|
75
|
+
expect(u2.user).toBe('jack');
|
|
76
|
+
|
|
77
|
+
const response1 = await request(app.callback()).get('/api/i1?user=john');
|
|
78
|
+
expect(response1.statusCode).toBe(200);
|
|
79
|
+
const response2 = await request(app.callback()).get('/api/i2?user=jeremy');
|
|
80
|
+
expect(response2.statusCode).toBe(200);
|
|
81
|
+
const response3 = await request(app.callback()).get('/api/i1');
|
|
82
|
+
expect(response3.statusCode).toBe(400);
|
|
83
|
+
const response4 = await request(app.callback()).get('/api/i2');
|
|
84
|
+
expect(response4.statusCode).toBe(400);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
@DBOSKoa.defaultArgValidate
|
|
89
|
+
class KnexKoa {
|
|
90
|
+
@knexds.transaction()
|
|
91
|
+
@dhttp.getApi('/api/i2')
|
|
92
|
+
static async insertTheOtherWay(user: string) {
|
|
93
|
+
const rows = await knexds
|
|
94
|
+
.client<greetings>('greetings')
|
|
95
|
+
.insert({ name: user, greet_count: 1 })
|
|
96
|
+
.onConflict('name')
|
|
97
|
+
.merge({ greet_count: knexds.client.raw('greetings.greet_count + 1') })
|
|
98
|
+
.returning('greet_count');
|
|
99
|
+
|
|
100
|
+
const row = rows.length > 0 ? rows[0] : undefined;
|
|
101
|
+
|
|
102
|
+
return { user, greet_count: row?.greet_count, now: Date.now() };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@dhttp.getApi('/api/i1')
|
|
106
|
+
@knexds.transaction()
|
|
107
|
+
static async insertOneWay(user: string) {
|
|
108
|
+
const rows = await knexds
|
|
109
|
+
.client<greetings>('greetings')
|
|
110
|
+
.insert({ name: user, greet_count: 1 })
|
|
111
|
+
.onConflict('name')
|
|
112
|
+
.merge({ greet_count: knexds.client.raw('greetings.greet_count + 1') })
|
|
113
|
+
.returning('greet_count');
|
|
114
|
+
const row = rows.length > 0 ? rows[0] : undefined;
|
|
115
|
+
|
|
116
|
+
return { user, greet_count: row?.greet_count, now: Date.now() };
|
|
117
|
+
}
|
|
118
|
+
}
|