@jskit-ai/database-runtime-postgres 0.1.156 → 0.1.158
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/package.json +10 -155
- package/patterns/postgres-application/PATTERN.md +80 -0
- package/patterns/postgres-application/example/.env.example +5 -0
- package/patterns/postgres-application/example/.github/workflows/verify.yml +38 -0
- package/patterns/postgres-application/example/knexfile.js +11 -0
- package/patterns/postgres-application/example/package.json +13 -0
- package/patterns/postgres-application/example/scripts/prepare-database.js +3 -0
- package/src/server/providers/PostgresDatabaseDriverProvider.js +16 -0
- package/test/applicationPattern.test.js +18 -0
- package/test/entrypoints.boundary.test.js +7 -6
- package/test/packageMetadata.test.js +16 -17
- package/test/providerRuntime.test.js +17 -27
- package/src/server/providers/DatabaseRuntimePostgresServiceProvider.js +0 -21
package/package.json
CHANGED
|
@@ -1,72 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/database-runtime-postgres",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.158",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
7
7
|
},
|
|
8
8
|
"exports": {
|
|
9
9
|
"./client": "./src/client/index.js",
|
|
10
|
-
"./server/providers/
|
|
10
|
+
"./server/providers/PostgresDatabaseDriverProvider": "./src/server/providers/PostgresDatabaseDriverProvider.js",
|
|
11
11
|
"./shared": "./src/shared/index.js",
|
|
12
12
|
"./shared/dialect": "./src/shared/dialect.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@jskit-ai/database-runtime": "0.1.
|
|
15
|
+
"@jskit-ai/database-runtime": "0.1.161",
|
|
16
|
+
"pg": "^8.13.1"
|
|
16
17
|
},
|
|
17
18
|
"jskit": {
|
|
18
19
|
"kind": "runtime",
|
|
19
|
-
"options": {
|
|
20
|
-
"db-host": {
|
|
21
|
-
"required": false,
|
|
22
|
-
"values": [],
|
|
23
|
-
"defaultValue": "localhost",
|
|
24
|
-
"promptLabel": "Database host",
|
|
25
|
-
"promptHint": "Postgres host (for example 127.0.0.1)"
|
|
26
|
-
},
|
|
27
|
-
"db-port": {
|
|
28
|
-
"required": false,
|
|
29
|
-
"values": [],
|
|
30
|
-
"defaultValue": "5432",
|
|
31
|
-
"promptLabel": "Database port",
|
|
32
|
-
"promptHint": "Postgres port (usually 5432)"
|
|
33
|
-
},
|
|
34
|
-
"db-name": {
|
|
35
|
-
"required": true,
|
|
36
|
-
"values": [],
|
|
37
|
-
"promptLabel": "Database name",
|
|
38
|
-
"promptHint": "Database name to connect to"
|
|
39
|
-
},
|
|
40
|
-
"db-user": {
|
|
41
|
-
"required": true,
|
|
42
|
-
"values": [],
|
|
43
|
-
"promptLabel": "Database user",
|
|
44
|
-
"promptHint": "Database username"
|
|
45
|
-
},
|
|
46
|
-
"db-password": {
|
|
47
|
-
"required": true,
|
|
48
|
-
"values": [],
|
|
49
|
-
"inputType": "password",
|
|
50
|
-
"promptLabel": "Database password",
|
|
51
|
-
"promptHint": "Database password"
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
20
|
"capabilities": {
|
|
55
21
|
"provides": [
|
|
56
|
-
"runtime.database.driver"
|
|
57
|
-
"runtime.database.driver.postgres"
|
|
22
|
+
"runtime.database.driver"
|
|
58
23
|
],
|
|
59
|
-
"requires": [
|
|
60
|
-
"runtime.database"
|
|
61
|
-
]
|
|
24
|
+
"requires": []
|
|
62
25
|
},
|
|
63
26
|
"runtime": {
|
|
64
27
|
"server": {
|
|
65
|
-
"providerEntrypoint": "src/server/providers/DatabaseRuntimePostgresServiceProvider.js",
|
|
66
28
|
"providers": [
|
|
67
29
|
{
|
|
68
|
-
"entrypoint": "src/server/providers/
|
|
69
|
-
"export": "
|
|
30
|
+
"entrypoint": "src/server/providers/PostgresDatabaseDriverProvider.js",
|
|
31
|
+
"export": "PostgresDatabaseDriverProvider"
|
|
70
32
|
}
|
|
71
33
|
]
|
|
72
34
|
},
|
|
@@ -79,7 +41,7 @@
|
|
|
79
41
|
"surfaces": [
|
|
80
42
|
{
|
|
81
43
|
"subpath": "./server",
|
|
82
|
-
"summary": "
|
|
44
|
+
"summary": "Provides the exclusive runtime.database.driver capability for PostgreSQL."
|
|
83
45
|
},
|
|
84
46
|
{
|
|
85
47
|
"subpath": "./shared",
|
|
@@ -89,115 +51,8 @@
|
|
|
89
51
|
"subpath": "./client",
|
|
90
52
|
"summary": "Exports no runtime API today (reserved client entrypoint)."
|
|
91
53
|
}
|
|
92
|
-
]
|
|
93
|
-
"containerTokens": {
|
|
94
|
-
"server": [
|
|
95
|
-
"runtime.database.driver.postgres"
|
|
96
|
-
],
|
|
97
|
-
"client": []
|
|
98
|
-
}
|
|
54
|
+
]
|
|
99
55
|
}
|
|
100
|
-
},
|
|
101
|
-
"ci": {
|
|
102
|
-
"environment": {
|
|
103
|
-
"DB_CLIENT": "pg",
|
|
104
|
-
"DB_HOST": "127.0.0.1",
|
|
105
|
-
"DB_PORT": "54320",
|
|
106
|
-
"DB_NAME": "jskit_ci",
|
|
107
|
-
"DB_USER": "jskit_ci",
|
|
108
|
-
"DB_PASSWORD": "jskit_ci_only_password"
|
|
109
|
-
},
|
|
110
|
-
"services": [
|
|
111
|
-
{
|
|
112
|
-
"id": "postgres",
|
|
113
|
-
"image": "postgres:16",
|
|
114
|
-
"environment": {
|
|
115
|
-
"POSTGRES_DB": "jskit_ci",
|
|
116
|
-
"POSTGRES_USER": "jskit_ci",
|
|
117
|
-
"POSTGRES_PASSWORD": "jskit_ci_only_password"
|
|
118
|
-
},
|
|
119
|
-
"ports": [
|
|
120
|
-
"54320:5432"
|
|
121
|
-
],
|
|
122
|
-
"healthCheck": {
|
|
123
|
-
"command": "pg_isready --username=jskit_ci --dbname=jskit_ci",
|
|
124
|
-
"interval": "10s",
|
|
125
|
-
"timeout": "5s",
|
|
126
|
-
"retries": 10
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
],
|
|
130
|
-
"steps": []
|
|
131
|
-
},
|
|
132
|
-
"mutations": {
|
|
133
|
-
"dependencies": {
|
|
134
|
-
"runtime": {
|
|
135
|
-
"@jskit-ai/database-runtime": "0.1.159",
|
|
136
|
-
"pg": "^8.13.1"
|
|
137
|
-
},
|
|
138
|
-
"dev": {}
|
|
139
|
-
},
|
|
140
|
-
"packageJson": {
|
|
141
|
-
"scripts": {}
|
|
142
|
-
},
|
|
143
|
-
"procfile": {},
|
|
144
|
-
"files": [],
|
|
145
|
-
"text": [
|
|
146
|
-
{
|
|
147
|
-
"file": ".env",
|
|
148
|
-
"op": "upsert-env",
|
|
149
|
-
"key": "DB_CLIENT",
|
|
150
|
-
"value": "pg",
|
|
151
|
-
"reason": "Configure database client driver for runtime wiring.",
|
|
152
|
-
"category": "runtime-config",
|
|
153
|
-
"id": "database-client-postgres"
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
"file": ".env",
|
|
157
|
-
"op": "upsert-env",
|
|
158
|
-
"key": "DB_HOST",
|
|
159
|
-
"value": "${option:db-host}",
|
|
160
|
-
"reason": "Configure database host.",
|
|
161
|
-
"category": "runtime-config",
|
|
162
|
-
"id": "database-host"
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"file": ".env",
|
|
166
|
-
"op": "upsert-env",
|
|
167
|
-
"key": "DB_PORT",
|
|
168
|
-
"value": "${option:db-port}",
|
|
169
|
-
"reason": "Configure database port.",
|
|
170
|
-
"category": "runtime-config",
|
|
171
|
-
"id": "database-port"
|
|
172
|
-
},
|
|
173
|
-
{
|
|
174
|
-
"file": ".env",
|
|
175
|
-
"op": "upsert-env",
|
|
176
|
-
"key": "DB_NAME",
|
|
177
|
-
"value": "${option:db-name}",
|
|
178
|
-
"reason": "Configure database name.",
|
|
179
|
-
"category": "runtime-config",
|
|
180
|
-
"id": "database-name"
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
"file": ".env",
|
|
184
|
-
"op": "upsert-env",
|
|
185
|
-
"key": "DB_USER",
|
|
186
|
-
"value": "${option:db-user}",
|
|
187
|
-
"reason": "Configure database user.",
|
|
188
|
-
"category": "runtime-config",
|
|
189
|
-
"id": "database-user"
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
"file": ".env",
|
|
193
|
-
"op": "upsert-env",
|
|
194
|
-
"key": "DB_PASSWORD",
|
|
195
|
-
"value": "${option:db-password}",
|
|
196
|
-
"reason": "Configure database password.",
|
|
197
|
-
"category": "runtime-config",
|
|
198
|
-
"id": "database-password"
|
|
199
|
-
}
|
|
200
|
-
]
|
|
201
56
|
}
|
|
202
57
|
}
|
|
203
58
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: database/postgres-application
|
|
3
|
+
title: PostgreSQL application database
|
|
4
|
+
summary: Configure a JSKIT application for PostgreSQL with a fixed driver, ordinary environment values, and rebuildable Knex migrations.
|
|
5
|
+
keywords: database, knex, migrations, pg, postgres, postgresql
|
|
6
|
+
requires: @jskit-ai/database-runtime-postgres
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# PostgreSQL application database
|
|
10
|
+
|
|
11
|
+
## Use when
|
|
12
|
+
|
|
13
|
+
Use this pattern when an application deliberately chooses PostgreSQL. Install
|
|
14
|
+
`@jskit-ai/database-runtime-postgres`; its normal npm dependencies provide the
|
|
15
|
+
database runtime, Knex, and `pg` without a package-setup wizard.
|
|
16
|
+
|
|
17
|
+
## Do not use when
|
|
18
|
+
|
|
19
|
+
Do not use this pattern for MySQL, a database-neutral library, or a service that
|
|
20
|
+
does not own its database connection. Do not install both JSKIT drivers unless
|
|
21
|
+
the application genuinely selects between them at runtime.
|
|
22
|
+
|
|
23
|
+
## Product decisions
|
|
24
|
+
|
|
25
|
+
Decide the database name, credentials, host, deployment secret source, backup
|
|
26
|
+
policy, and application migrations. Those are application and environment
|
|
27
|
+
decisions, not framework questions.
|
|
28
|
+
|
|
29
|
+
## Invariants
|
|
30
|
+
|
|
31
|
+
- The application depends directly on the selected JSKIT driver.
|
|
32
|
+
- Credentials stay outside Git.
|
|
33
|
+
- `knexfile.js` fixes `pg`; a single-driver application does not require
|
|
34
|
+
`DB_CLIENT`.
|
|
35
|
+
- Schema changes are ordinary immutable migrations.
|
|
36
|
+
- The current package graph, environment, and migrations are authoritative.
|
|
37
|
+
|
|
38
|
+
## Framework APIs
|
|
39
|
+
|
|
40
|
+
Use `createKnexMigrationConfigFromApp()` from
|
|
41
|
+
`@jskit-ai/database-runtime/server/knexMigrationConfig`. The running JSKIT
|
|
42
|
+
application automatically selects the sole installed database driver, while
|
|
43
|
+
Knex discovers package-owned migrations from the installed dependency graph.
|
|
44
|
+
|
|
45
|
+
## Example files
|
|
46
|
+
|
|
47
|
+
`example/package.json` contains the runtime dependency and database scripts.
|
|
48
|
+
`example/knexfile.js` loads an optional local `.env` and fixes the PostgreSQL
|
|
49
|
+
dialect. `example/scripts/prepare-database.js` is the portable
|
|
50
|
+
migrate-then-seed entrypoint for managed sessions and deployments.
|
|
51
|
+
`example/.env.example` names the five connection values without a secret.
|
|
52
|
+
|
|
53
|
+
## Variation points
|
|
54
|
+
|
|
55
|
+
Change scripts, migration location, connection values, and secret injection to
|
|
56
|
+
fit the application. Supply `DATABASE_URL` instead of individual values when
|
|
57
|
+
the environment owns a URL. Add `DB_CLIENT=pg` only when a shared external tool
|
|
58
|
+
explicitly needs a dialect selector. When the product needs initial data,
|
|
59
|
+
import one idempotent app-owned seed function in `prepare-database.js` and pass
|
|
60
|
+
it as `seed` to `prepareDatabaseFromApp()`.
|
|
61
|
+
|
|
62
|
+
## Verification
|
|
63
|
+
|
|
64
|
+
- Install dependencies once with `npm install`.
|
|
65
|
+
- Run `npm run db:prepare` against a fresh disposable database.
|
|
66
|
+
- Run `npm run db:migrate:status` and the application verification command.
|
|
67
|
+
- Exercise one transaction and one negative connection case.
|
|
68
|
+
- When a seed exists, run `db:prepare` twice and require the second run to be safe.
|
|
69
|
+
|
|
70
|
+
`example/.github/workflows/verify.yml` is a normal app-owned CI workflow with
|
|
71
|
+
an explicit PostgreSQL service. Adapt it as source rather than generating it
|
|
72
|
+
from package metadata.
|
|
73
|
+
|
|
74
|
+
## Avoid
|
|
75
|
+
|
|
76
|
+
- framework questionnaires for credentials
|
|
77
|
+
- generated `.env` secrets
|
|
78
|
+
- depending on a live schema as the source contract
|
|
79
|
+
- a second driver installed “just in case”
|
|
80
|
+
- migration receipts, provenance, replay logs, or generator ownership
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Verify
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
verify:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
services:
|
|
11
|
+
postgres:
|
|
12
|
+
image: postgres:17
|
|
13
|
+
env:
|
|
14
|
+
POSTGRES_DB: app_test
|
|
15
|
+
POSTGRES_USER: app_test
|
|
16
|
+
POSTGRES_PASSWORD: app_test_password
|
|
17
|
+
ports:
|
|
18
|
+
- 5432:5432
|
|
19
|
+
options: >-
|
|
20
|
+
--health-cmd="pg_isready -U app_test -d app_test"
|
|
21
|
+
--health-interval=10s
|
|
22
|
+
--health-timeout=5s
|
|
23
|
+
--health-retries=10
|
|
24
|
+
env:
|
|
25
|
+
DB_HOST: 127.0.0.1
|
|
26
|
+
DB_PORT: 5432
|
|
27
|
+
DB_NAME: app_test
|
|
28
|
+
DB_USER: app_test
|
|
29
|
+
DB_PASSWORD: app_test_password
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version-file: .nvmrc
|
|
35
|
+
cache: npm
|
|
36
|
+
- run: npm ci
|
|
37
|
+
- run: npm run db:migrate
|
|
38
|
+
- run: npm run verify
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createKnexMigrationConfigFromApp } from "@jskit-ai/database-runtime/server/knexMigrationConfig";
|
|
2
|
+
|
|
3
|
+
try {
|
|
4
|
+
process.loadEnvFile?.(".env");
|
|
5
|
+
} catch (error) {
|
|
6
|
+
if (error?.code !== "ENOENT") {
|
|
7
|
+
throw error;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default await createKnexMigrationConfigFromApp({ client: "pg" });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"private": true,
|
|
3
|
+
"type": "module",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"db:prepare": "node ./scripts/prepare-database.js",
|
|
6
|
+
"db:migrate": "knex --knexfile ./knexfile.js migrate:latest",
|
|
7
|
+
"db:migrate:rollback": "knex --knexfile ./knexfile.js migrate:rollback",
|
|
8
|
+
"db:migrate:status": "knex --knexfile ./knexfile.js migrate:list"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@jskit-ai/database-runtime-postgres": "0.1.158"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
2
|
+
import * as postgresDriver from "../../shared/index.js";
|
|
3
|
+
|
|
4
|
+
const PostgresDatabaseDriverProvider = defineProvider({
|
|
5
|
+
id: "runtime.database.driver.postgres",
|
|
6
|
+
provides: {
|
|
7
|
+
driver: "runtime.database.driver"
|
|
8
|
+
},
|
|
9
|
+
setup() {
|
|
10
|
+
return {
|
|
11
|
+
driver: Object.freeze({ ...postgresDriver })
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export { PostgresDatabaseDriverProvider };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
|
|
5
|
+
const patternUrl = new URL("../patterns/postgres-application/", import.meta.url);
|
|
6
|
+
|
|
7
|
+
test("PostgreSQL application pattern is driver-fixed and questionnaire-free", async () => {
|
|
8
|
+
const [document, manifestSource, knexfile] = await Promise.all([
|
|
9
|
+
readFile(new URL("PATTERN.md", patternUrl), "utf8"),
|
|
10
|
+
readFile(new URL("example/package.json", patternUrl), "utf8"),
|
|
11
|
+
readFile(new URL("example/knexfile.js", patternUrl), "utf8")
|
|
12
|
+
]);
|
|
13
|
+
const manifest = JSON.parse(manifestSource);
|
|
14
|
+
|
|
15
|
+
assert.equal(manifest.dependencies["@jskit-ai/database-runtime-postgres"], "0.1.157");
|
|
16
|
+
assert.match(knexfile, /client: "pg"/u);
|
|
17
|
+
assert.doesNotMatch(`${document}\n${knexfile}`, /promptLabel|promptHint|\$\{option:/u);
|
|
18
|
+
});
|
|
@@ -4,15 +4,15 @@ import test from "node:test";
|
|
|
4
4
|
|
|
5
5
|
import * as clientApi from "../src/client/index.js";
|
|
6
6
|
import * as sharedApi from "../src/shared/index.js";
|
|
7
|
-
import {
|
|
7
|
+
import { PostgresDatabaseDriverProvider } from "../src/server/providers/PostgresDatabaseDriverProvider.js";
|
|
8
8
|
|
|
9
9
|
test("package exports include explicit shared and provider entrypoints", async () => {
|
|
10
10
|
const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
11
11
|
const exportsMap = packageJson && typeof packageJson === "object" ? packageJson.exports : {};
|
|
12
12
|
assert.equal(exportsMap["./server"], undefined);
|
|
13
13
|
assert.equal(
|
|
14
|
-
exportsMap["./server/providers/
|
|
15
|
-
"./src/server/providers/
|
|
14
|
+
exportsMap["./server/providers/PostgresDatabaseDriverProvider"],
|
|
15
|
+
"./src/server/providers/PostgresDatabaseDriverProvider.js"
|
|
16
16
|
);
|
|
17
17
|
assert.equal(exportsMap["./shared"], "./src/shared/index.js");
|
|
18
18
|
});
|
|
@@ -21,12 +21,13 @@ test("client entrypoint exports no postgres runtime api", () => {
|
|
|
21
21
|
assert.deepEqual(Object.keys(clientApi), []);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
test("server provider module exports postgres
|
|
25
|
-
assert.equal(
|
|
24
|
+
test("server provider module exports the declarative postgres driver provider", () => {
|
|
25
|
+
assert.equal(PostgresDatabaseDriverProvider.id, "runtime.database.driver.postgres");
|
|
26
|
+
assert.deepEqual(PostgresDatabaseDriverProvider.provides, { driver: "runtime.database.driver" });
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
test("shared entrypoint exports postgres dialect helpers", () => {
|
|
29
30
|
assert.equal(sharedApi.DIALECT_ID, "pg");
|
|
30
31
|
assert.equal(sharedApi.getDialectId(), "pg");
|
|
31
|
-
assert.equal(typeof sharedApi.
|
|
32
|
+
assert.equal(typeof sharedApi.PostgresDatabaseDriverProvider, "undefined");
|
|
32
33
|
});
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
import test from "node:test";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
3
6
|
import packageJson from "../package.json" with { type: "json" };
|
|
4
7
|
|
|
5
|
-
const
|
|
6
|
-
import { DIALECT_ID } from "../src/shared/dialect.js";
|
|
8
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
9
|
|
|
8
|
-
test("database-runtime-postgres
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
test("database-runtime-postgres owns its driver while CI remains app-owned source", async () => {
|
|
11
|
+
const workflow = await readFile(
|
|
12
|
+
path.join(PACKAGE_ROOT, "patterns/postgres-application/example/.github/workflows/verify.yml"),
|
|
13
|
+
"utf8"
|
|
14
|
+
);
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
assert.equal(
|
|
16
|
-
assert.equal(
|
|
17
|
-
assert.equal(
|
|
18
|
-
assert.
|
|
19
|
-
assert.
|
|
20
|
-
assert.match(
|
|
21
|
-
|
|
22
|
-
const clientMutation = packageMetadata.mutations.text.find((entry) => entry.key === "DB_CLIENT");
|
|
23
|
-
assert.equal(clientMutation.value, DIALECT_ID);
|
|
16
|
+
assert.equal(packageJson.dependencies.pg, "^8.13.1");
|
|
17
|
+
assert.equal(Object.hasOwn(packageJson.jskit, "options"), false);
|
|
18
|
+
assert.equal(Object.hasOwn(packageJson.jskit, "mutations"), false);
|
|
19
|
+
assert.equal(Object.hasOwn(packageJson.jskit, "ci"), false);
|
|
20
|
+
assert.match(workflow, /image: postgres:17/u);
|
|
21
|
+
assert.match(workflow, /npm run db:migrate/u);
|
|
22
|
+
assert.match(workflow, /npm run verify/u);
|
|
24
23
|
});
|
|
@@ -1,33 +1,23 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
1
|
import assert from "node:assert/strict";
|
|
3
|
-
import
|
|
2
|
+
import test from "node:test";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { createCapabilityRuntime, defineProvider } from "@jskit-ai/kernel/shared/capabilities";
|
|
5
|
+
import { PostgresDatabaseDriverProvider } from "../src/server/providers/PostgresDatabaseDriverProvider.js";
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (!singletons.has(token)) {
|
|
17
|
-
throw new Error(`Token ${String(token)} is not registered.`);
|
|
18
|
-
}
|
|
19
|
-
return singletons.get(token);
|
|
7
|
+
test("PostgresDatabaseDriverProvider provides the exclusive database driver capability", async () => {
|
|
8
|
+
let driver;
|
|
9
|
+
const consumer = defineProvider({
|
|
10
|
+
id: "test.postgres.consumer",
|
|
11
|
+
requires: { databaseDriver: "runtime.database.driver" },
|
|
12
|
+
setup({ databaseDriver }) {
|
|
13
|
+
driver = databaseDriver;
|
|
14
|
+
return {};
|
|
20
15
|
}
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
test("DatabaseRuntimePostgresServiceProvider registers postgres driver api", () => {
|
|
25
|
-
const app = createSingletonApp();
|
|
26
|
-
const provider = new DatabaseRuntimePostgresServiceProvider();
|
|
27
|
-
provider.register(app);
|
|
16
|
+
});
|
|
17
|
+
const runtime = createCapabilityRuntime({ providers: [PostgresDatabaseDriverProvider, consumer] });
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
assert.equal(
|
|
32
|
-
|
|
19
|
+
await runtime.start();
|
|
20
|
+
assert.equal(driver.DIALECT_ID, "pg");
|
|
21
|
+
assert.equal(driver.getDialectId(), "pg");
|
|
22
|
+
await runtime.shutdown();
|
|
33
23
|
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as postgresDialect from "../../shared/index.js";
|
|
2
|
-
|
|
3
|
-
const POSTGRES_DATABASE_DRIVER_API = Object.freeze({
|
|
4
|
-
...postgresDialect
|
|
5
|
-
});
|
|
6
|
-
|
|
7
|
-
class DatabaseRuntimePostgresServiceProvider {
|
|
8
|
-
static id = "runtime.database.driver.postgres";
|
|
9
|
-
|
|
10
|
-
register(app) {
|
|
11
|
-
if (!app || typeof app.singleton !== "function") {
|
|
12
|
-
throw new Error("DatabaseRuntimePostgresServiceProvider requires application singleton().");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
app.singleton("runtime.database.driver.postgres", () => POSTGRES_DATABASE_DRIVER_API);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
boot() {}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { DatabaseRuntimePostgresServiceProvider };
|