@jskit-ai/database-runtime 0.1.57 → 0.1.58
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.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/database-runtime",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.58",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
dependsOn: [
|
|
7
7
|
"@jskit-ai/kernel"
|
|
@@ -58,7 +58,7 @@ export default Object.freeze({
|
|
|
58
58
|
mutations: {
|
|
59
59
|
dependencies: {
|
|
60
60
|
runtime: {
|
|
61
|
-
"@jskit-ai/kernel": "0.1.
|
|
61
|
+
"@jskit-ai/kernel": "0.1.58",
|
|
62
62
|
"dotenv": "^16.4.5",
|
|
63
63
|
"knex": "^3.1.0"
|
|
64
64
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/database-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.58",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"./shared/transactions": "./src/shared/transactions.js"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@jskit-ai/kernel": "0.1.
|
|
28
|
+
"@jskit-ai/kernel": "0.1.58"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -141,6 +141,11 @@ function createKnexInstance(scope) {
|
|
|
141
141
|
class DatabaseRuntimeServiceProvider {
|
|
142
142
|
static id = "runtime.database";
|
|
143
143
|
|
|
144
|
+
constructor() {
|
|
145
|
+
this.knexInstance = null;
|
|
146
|
+
this.knexDestroyed = false;
|
|
147
|
+
}
|
|
148
|
+
|
|
144
149
|
register(app) {
|
|
145
150
|
if (!app || typeof app.singleton !== "function" || typeof app.has !== "function") {
|
|
146
151
|
throw new Error("DatabaseRuntimeServiceProvider requires application singleton()/has().");
|
|
@@ -153,7 +158,12 @@ class DatabaseRuntimeServiceProvider {
|
|
|
153
158
|
}
|
|
154
159
|
|
|
155
160
|
if (!app.has("jskit.database.knex")) {
|
|
156
|
-
app.singleton("jskit.database.knex", (scope) =>
|
|
161
|
+
app.singleton("jskit.database.knex", (scope) => {
|
|
162
|
+
const knex = createKnexInstance(scope);
|
|
163
|
+
this.knexInstance = knex;
|
|
164
|
+
this.knexDestroyed = false;
|
|
165
|
+
return knex;
|
|
166
|
+
});
|
|
157
167
|
}
|
|
158
168
|
|
|
159
169
|
if (!app.has("jskit.database.transactionManager")) {
|
|
@@ -165,6 +175,38 @@ class DatabaseRuntimeServiceProvider {
|
|
|
165
175
|
}
|
|
166
176
|
|
|
167
177
|
boot() {}
|
|
178
|
+
|
|
179
|
+
async shutdown(app) {
|
|
180
|
+
if (this.knexDestroyed) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
let knex = this.knexInstance || null;
|
|
185
|
+
|
|
186
|
+
if (!knex) {
|
|
187
|
+
const container = app?.container;
|
|
188
|
+
const instanceRecord =
|
|
189
|
+
container && typeof container.findInstanceRecord === "function"
|
|
190
|
+
? container.findInstanceRecord("jskit.database.knex")
|
|
191
|
+
: null;
|
|
192
|
+
knex = instanceRecord?.value || null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!knex && app && typeof app.has === "function" && app.has("jskit.database.knex") && typeof app.make === "function") {
|
|
196
|
+
try {
|
|
197
|
+
knex = app.make("jskit.database.knex");
|
|
198
|
+
} catch {
|
|
199
|
+
knex = null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!knex || typeof knex.destroy !== "function") {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
await knex.destroy();
|
|
208
|
+
this.knexDestroyed = true;
|
|
209
|
+
}
|
|
168
210
|
}
|
|
169
211
|
|
|
170
212
|
export { DatabaseRuntimeServiceProvider };
|
package/src/shared/dateUtils.js
CHANGED
|
@@ -42,6 +42,14 @@ function toNullableDateTime(value) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function toDatabaseDateTimeUtc(value) {
|
|
45
|
+
if (value == null) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
const date = toDateOrThrow(value);
|
|
46
54
|
const year = date.getUTCFullYear();
|
|
47
55
|
const month = pad(date.getUTCMonth() + 1);
|
package/test/dateUtils.test.js
CHANGED
|
@@ -11,6 +11,13 @@ test("toDatabaseDateTimeUtc formats DATETIME(3) UTC string", () => {
|
|
|
11
11
|
assert.equal(toDatabaseDateTimeUtc(new Date("2024-01-01T01:02:03.045Z")), "2024-01-01 01:02:03.045");
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
test("toDatabaseDateTimeUtc preserves nullable empty values", () => {
|
|
15
|
+
assert.equal(toDatabaseDateTimeUtc(null), null);
|
|
16
|
+
assert.equal(toDatabaseDateTimeUtc(undefined), null);
|
|
17
|
+
assert.equal(toDatabaseDateTimeUtc(""), null);
|
|
18
|
+
assert.equal(toDatabaseDateTimeUtc(" "), null);
|
|
19
|
+
});
|
|
20
|
+
|
|
14
21
|
test("date utils throw on invalid date", () => {
|
|
15
22
|
assert.throws(() => toIsoString("not-a-date"), /Invalid date value\./);
|
|
16
23
|
assert.throws(() => toDatabaseDateTimeUtc("not-a-date"), /Invalid date value\./);
|
|
@@ -50,8 +50,12 @@ function createSingletonApp() {
|
|
|
50
50
|
|
|
51
51
|
function createKnexStub() {
|
|
52
52
|
return {
|
|
53
|
+
destroyCalls: 0,
|
|
53
54
|
async transaction(callback) {
|
|
54
55
|
return callback({ trxId: "trx-1" });
|
|
56
|
+
},
|
|
57
|
+
async destroy() {
|
|
58
|
+
this.destroyCalls += 1;
|
|
55
59
|
}
|
|
56
60
|
};
|
|
57
61
|
}
|
|
@@ -198,3 +202,18 @@ test("DatabaseRuntimeServiceProvider resolves knex config from DATABASE_URL when
|
|
|
198
202
|
assert.equal(knex.__config.connection.password, "urlpass");
|
|
199
203
|
});
|
|
200
204
|
});
|
|
205
|
+
|
|
206
|
+
test("DatabaseRuntimeServiceProvider destroys resolved knex during shutdown", async () => {
|
|
207
|
+
const app = createSingletonApp();
|
|
208
|
+
const knex = createKnexStub();
|
|
209
|
+
app.instance("jskit.database.knex", knex);
|
|
210
|
+
|
|
211
|
+
const provider = new DatabaseRuntimeServiceProvider();
|
|
212
|
+
provider.register(app);
|
|
213
|
+
|
|
214
|
+
await provider.shutdown(app);
|
|
215
|
+
assert.equal(knex.destroyCalls, 1);
|
|
216
|
+
|
|
217
|
+
await provider.shutdown(app);
|
|
218
|
+
assert.equal(knex.destroyCalls, 1);
|
|
219
|
+
});
|