@veap/database 0.1.0 → 0.1.1
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/README.md +3 -2
- package/dist/casts.js +1 -1
- package/dist/composition.d.ts +15 -0
- package/dist/composition.js +26 -0
- package/dist/connection.d.ts +1 -1
- package/dist/connection.js +9 -5
- package/dist/factory.d.ts +1 -1
- package/dist/factory.js +1 -1
- package/dist/index.d.ts +18 -16
- package/dist/index.js +18 -16
- package/dist/migration-provider.d.ts +2 -0
- package/dist/migration-provider.js +27 -6
- package/dist/migrations/index.d.ts +3 -3
- package/dist/migrations/index.js +3 -3
- package/dist/migrations/runner.d.ts +1 -1
- package/dist/migrations/runner.js +20 -19
- package/dist/migrations/schema-builder.js +1 -1
- package/dist/model.d.ts +4 -4
- package/dist/model.js +25 -11
- package/dist/provider.d.ts +2 -1
- package/dist/provider.js +62 -8
- package/dist/query-builder.d.ts +6 -6
- package/dist/query-builder.js +40 -6
- package/dist/relations/belongs-to-many.d.ts +3 -3
- package/dist/relations/belongs-to-many.js +2 -2
- package/dist/relations/belongs-to.d.ts +3 -3
- package/dist/relations/belongs-to.js +1 -1
- package/dist/relations/eager-loader.d.ts +1 -1
- package/dist/relations/eager-loader.js +3 -1
- package/dist/relations/has-many.d.ts +3 -3
- package/dist/relations/has-many.js +1 -1
- package/dist/relations/has-one.d.ts +3 -3
- package/dist/relations/has-one.js +1 -1
- package/dist/relations/index.d.ts +11 -11
- package/dist/relations/index.js +11 -11
- package/dist/relations/morph-many.d.ts +3 -3
- package/dist/relations/morph-many.js +2 -2
- package/dist/relations/morph-one.d.ts +3 -3
- package/dist/relations/morph-one.js +2 -2
- package/dist/relations/morph-to-many.d.ts +3 -3
- package/dist/relations/morph-to-many.js +3 -3
- package/dist/relations/morph-to.d.ts +3 -3
- package/dist/relations/morph-to.js +3 -3
- package/dist/relations/relation.d.ts +2 -2
- package/dist/scopes.d.ts +2 -2
- package/dist/seeder.js +2 -2
- package/dist/tokens.d.ts +10 -0
- package/dist/tokens.js +8 -0
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
[](https://github.com/veapjs/veap-database/actions/workflows/CI.yml)
|
|
2
|
+
[](https://github.com/veapjs/veap-database/actions/workflows/RELEASE.yml)
|
|
3
|
+
[](https://www.npmjs.com/package/@veap/database)
|
|
3
4
|
|
|
4
5
|
# @veap/database
|
|
5
6
|
|
package/dist/casts.js
CHANGED
|
@@ -57,7 +57,7 @@ export function serializeForStorage(value, type, clientType) {
|
|
|
57
57
|
}
|
|
58
58
|
switch (type) {
|
|
59
59
|
case "json":
|
|
60
|
-
return JSON.stringify(value);
|
|
60
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
61
61
|
case "boolean":
|
|
62
62
|
if (clientType?.includes("sqlite")) {
|
|
63
63
|
return value ? 1 : 0;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ServiceProvider } from "@veap/kernel";
|
|
2
|
+
declare module "@veap/kernel" {
|
|
3
|
+
interface ApplicationBuilder {
|
|
4
|
+
/**
|
|
5
|
+
* Registers host application migrations with IoC and configures MigrationServiceProvider.
|
|
6
|
+
*/
|
|
7
|
+
withMigrations(migrations: any[]): this;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
declare class MigrationsConfigProvider extends ServiceProvider {
|
|
11
|
+
private migrations;
|
|
12
|
+
constructor(container: any, migrations?: any[]);
|
|
13
|
+
register(): void;
|
|
14
|
+
}
|
|
15
|
+
export { MigrationsConfigProvider };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ApplicationBuilder, ServiceProvider } from "@veap/kernel";
|
|
2
|
+
import { MigrationServiceProvider } from "./migration-provider.js";
|
|
3
|
+
import { APP_MIGRATIONS } from "./tokens.js";
|
|
4
|
+
class MigrationsConfigProvider extends ServiceProvider {
|
|
5
|
+
migrations;
|
|
6
|
+
constructor(container, migrations = []) {
|
|
7
|
+
super(container);
|
|
8
|
+
this.migrations = migrations;
|
|
9
|
+
}
|
|
10
|
+
register() {
|
|
11
|
+
this.container.register({
|
|
12
|
+
token: APP_MIGRATIONS,
|
|
13
|
+
useValue: this.migrations,
|
|
14
|
+
});
|
|
15
|
+
this.container.register({
|
|
16
|
+
token: "AppMigrations",
|
|
17
|
+
useValue: this.migrations,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!ApplicationBuilder.prototype.withMigrations) {
|
|
22
|
+
ApplicationBuilder.prototype.withMigrations = function (migrations) {
|
|
23
|
+
return this.use((c) => new MigrationsConfigProvider(c, migrations)).use(MigrationServiceProvider);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export { MigrationsConfigProvider };
|
package/dist/connection.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { type Knex } from "knex";
|
|
3
|
-
import type { DatabaseConfig, PostgresSslConfig, PostgresSslOptions, TransactionOptions } from "./types";
|
|
3
|
+
import type { DatabaseConfig, PostgresSslConfig, PostgresSslOptions, TransactionOptions } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* AsyncLocalStorage holding the currently active Knex transaction for the asynchronous execution context.
|
|
6
6
|
*/
|
package/dist/connection.js
CHANGED
|
@@ -2,8 +2,8 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import knex from "knex";
|
|
5
|
-
import { DatabaseError } from "./errors";
|
|
6
|
-
import { debug, warn } from "./logger";
|
|
5
|
+
import { DatabaseError } from "./errors.js";
|
|
6
|
+
import { debug, warn } from "./logger.js";
|
|
7
7
|
const globalForDb = globalThis;
|
|
8
8
|
/**
|
|
9
9
|
* AsyncLocalStorage holding the currently active Knex transaction for the asynchronous execution context.
|
|
@@ -90,9 +90,13 @@ export function resolveSqliteFilename(filename) {
|
|
|
90
90
|
}
|
|
91
91
|
if (!clean.startsWith(":memory:")) {
|
|
92
92
|
try {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
94
|
+
/* turbopackIgnore: true */
|
|
95
|
+
const resolvedPath = path.resolve(clean);
|
|
96
|
+
fs.mkdirSync(path.dirname(resolvedPath), {
|
|
97
|
+
recursive: true,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
96
100
|
}
|
|
97
101
|
catch {
|
|
98
102
|
// Read-only filesystem etc. Let the driver surface its own error.
|
package/dist/factory.d.ts
CHANGED
package/dist/factory.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
export { default as knex, type Knex } from "knex";
|
|
2
|
-
export * from "./casts";
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
8
|
-
export * from "./
|
|
9
|
-
export * from "./
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./
|
|
12
|
-
export * from "./
|
|
13
|
-
export * from "./
|
|
14
|
-
export * from "./
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./
|
|
2
|
+
export * from "./casts.js";
|
|
3
|
+
export * from "./composition.js";
|
|
4
|
+
export * from "./connection.js";
|
|
5
|
+
export * from "./errors.js";
|
|
6
|
+
export * from "./events.js";
|
|
7
|
+
export * from "./factory.js";
|
|
8
|
+
export * from "./logger.js";
|
|
9
|
+
export * from "./migration-provider.js";
|
|
10
|
+
export * from "./migrations/index.js";
|
|
11
|
+
export * from "./model.js";
|
|
12
|
+
export * from "./provider.js";
|
|
13
|
+
export * from "./query-builder.js";
|
|
14
|
+
export * from "./relations/index.js";
|
|
15
|
+
export * from "./scopes.js";
|
|
16
|
+
export * from "./seeder.js";
|
|
17
|
+
export * from "./tokens.js";
|
|
18
|
+
export * from "./types.js";
|
|
19
|
+
export * from "./utils.js";
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
export { default as knex } from "knex";
|
|
2
|
-
export * from "./casts";
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
6
|
-
export * from "./
|
|
7
|
-
export * from "./
|
|
8
|
-
export * from "./
|
|
9
|
-
export * from "./
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./
|
|
12
|
-
export * from "./
|
|
13
|
-
export * from "./
|
|
14
|
-
export * from "./
|
|
15
|
-
export * from "./
|
|
16
|
-
export * from "./
|
|
17
|
-
export * from "./
|
|
2
|
+
export * from "./casts.js";
|
|
3
|
+
export * from "./composition.js";
|
|
4
|
+
export * from "./connection.js";
|
|
5
|
+
export * from "./errors.js";
|
|
6
|
+
export * from "./events.js";
|
|
7
|
+
export * from "./factory.js";
|
|
8
|
+
export * from "./logger.js";
|
|
9
|
+
export * from "./migration-provider.js";
|
|
10
|
+
export * from "./migrations/index.js";
|
|
11
|
+
export * from "./model.js";
|
|
12
|
+
export * from "./provider.js";
|
|
13
|
+
export * from "./query-builder.js";
|
|
14
|
+
export * from "./relations/index.js";
|
|
15
|
+
export * from "./scopes.js";
|
|
16
|
+
export * from "./seeder.js";
|
|
17
|
+
export * from "./tokens.js";
|
|
18
|
+
export * from "./types.js";
|
|
19
|
+
export * from "./utils.js";
|
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
import { ServiceProvider } from "@veap/kernel";
|
|
2
|
-
import { runMigrations } from "./migrations/runner";
|
|
2
|
+
import { runMigrations } from "./migrations/runner.js";
|
|
3
|
+
import { APP_MIGRATIONS } from "./tokens.js";
|
|
3
4
|
export class MigrationServiceProvider extends ServiceProvider {
|
|
5
|
+
migrations;
|
|
6
|
+
constructor(container, migrations) {
|
|
7
|
+
super(container);
|
|
8
|
+
this.migrations = migrations;
|
|
9
|
+
}
|
|
4
10
|
register() {
|
|
5
|
-
|
|
11
|
+
if (this.migrations?.length) {
|
|
12
|
+
this.container.register({
|
|
13
|
+
token: APP_MIGRATIONS,
|
|
14
|
+
useValue: this.migrations,
|
|
15
|
+
});
|
|
16
|
+
this.container.register({
|
|
17
|
+
token: "AppMigrations",
|
|
18
|
+
useValue: this.migrations,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
6
21
|
}
|
|
7
22
|
async boot() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (
|
|
11
|
-
await
|
|
23
|
+
let appMigrations = this.migrations;
|
|
24
|
+
if (!appMigrations?.length) {
|
|
25
|
+
if (this.container.has(APP_MIGRATIONS)) {
|
|
26
|
+
appMigrations = await this.container.resolve(APP_MIGRATIONS);
|
|
12
27
|
}
|
|
28
|
+
else if (this.container.has("AppMigrations")) {
|
|
29
|
+
appMigrations = await this.container.resolve("AppMigrations");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (appMigrations?.length) {
|
|
33
|
+
await runMigrations("app", appMigrations);
|
|
13
34
|
}
|
|
14
35
|
}
|
|
15
36
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./generator";
|
|
2
|
-
export * from "./runner";
|
|
3
|
-
export * from "./schema-builder";
|
|
1
|
+
export * from "./generator.js";
|
|
2
|
+
export * from "./runner.js";
|
|
3
|
+
export * from "./schema-builder.js";
|
package/dist/migrations/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./generator";
|
|
2
|
-
export * from "./runner";
|
|
3
|
-
export * from "./schema-builder";
|
|
1
|
+
export * from "./generator.js";
|
|
2
|
+
export * from "./runner.js";
|
|
3
|
+
export * from "./schema-builder.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import { getKnex } from "../connection";
|
|
3
|
-
import { debug, warn } from "../logger";
|
|
4
|
-
import { Schema } from "./schema-builder";
|
|
2
|
+
import { getKnex } from "../connection.js";
|
|
3
|
+
import { debug, warn } from "../logger.js";
|
|
4
|
+
import { Schema } from "./schema-builder.js";
|
|
5
5
|
async function ensureMigrationsTable(knex = getKnex()) {
|
|
6
6
|
try {
|
|
7
7
|
const hasTable = await knex.schema.hasTable("migrations");
|
|
@@ -27,6 +27,19 @@ async function ensureMigrationsTable(knex = getKnex()) {
|
|
|
27
27
|
warn("veap:migration", "Failed to ensure migrations table:", error);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
async function acquireAdvisoryLockIfPostgres(tx, knex) {
|
|
31
|
+
const clientName = knex?.client?.config?.client || "";
|
|
32
|
+
if (typeof clientName === "string" &&
|
|
33
|
+
(clientName.includes("pg") || clientName.includes("postgres"))) {
|
|
34
|
+
const lockId = 123456;
|
|
35
|
+
try {
|
|
36
|
+
await tx.raw("SELECT pg_advisory_xact_lock(?)", [lockId]);
|
|
37
|
+
}
|
|
38
|
+
catch (_e) {
|
|
39
|
+
debug("veap:migration", "Could not acquire advisory lock, continuing...");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
30
43
|
/**
|
|
31
44
|
* Creates a compatibility DB adapter for migrations that provides `.execute(query)`
|
|
32
45
|
* wrapping `trx.raw(query)`, while also being directly callable as a Knex query builder
|
|
@@ -67,14 +80,8 @@ export async function runMigrations(scope, migrations) {
|
|
|
67
80
|
return;
|
|
68
81
|
await ensureMigrationsTable(knex);
|
|
69
82
|
await knex.transaction(async (tx) => {
|
|
70
|
-
// Acquire advisory lock
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
await tx.raw("SELECT pg_advisory_xact_lock(?)", [lockId]);
|
|
74
|
-
}
|
|
75
|
-
catch (_e) {
|
|
76
|
-
debug("veap:migration", "Could not acquire advisory lock, continuing...");
|
|
77
|
-
}
|
|
83
|
+
// Acquire advisory lock only if running on PostgreSQL
|
|
84
|
+
await acquireAdvisoryLockIfPostgres(tx, knex);
|
|
78
85
|
debug("veap:migration", `Running migrations for scope: ${scope}`);
|
|
79
86
|
// 1. Get executed migrations for this scope
|
|
80
87
|
const executed = await tx("migrations")
|
|
@@ -131,14 +138,8 @@ export async function rollbackMigrations(scope, migrations) {
|
|
|
131
138
|
return;
|
|
132
139
|
await ensureMigrationsTable(knex);
|
|
133
140
|
await knex.transaction(async (tx) => {
|
|
134
|
-
// Acquire advisory lock
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
await tx.raw("SELECT pg_advisory_xact_lock(?)", [lockId]);
|
|
138
|
-
}
|
|
139
|
-
catch (_e) {
|
|
140
|
-
debug("veap:migration", "Could not acquire advisory lock, continuing...");
|
|
141
|
-
}
|
|
141
|
+
// Acquire advisory lock only if running on PostgreSQL
|
|
142
|
+
await acquireAdvisoryLockIfPostgres(tx, knex);
|
|
142
143
|
// 1. Get executed migrations for this scope ordered by batch desc
|
|
143
144
|
const executed = await tx("migrations")
|
|
144
145
|
.select("name", "batch")
|
package/dist/model.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { type CastType } from "./casts";
|
|
2
|
-
import { ModelQueryBuilder } from "./query-builder";
|
|
3
|
-
import { BelongsTo, BelongsToMany, HasMany, HasOne, MorphedByMany, MorphMany, MorphOne, MorphTo, MorphToMany } from "./relations";
|
|
4
|
-
import type { GlobalScope } from "./scopes";
|
|
1
|
+
import { type CastType } from "./casts.js";
|
|
2
|
+
import { ModelQueryBuilder } from "./query-builder.js";
|
|
3
|
+
import { BelongsTo, BelongsToMany, HasMany, HasOne, MorphedByMany, MorphMany, MorphOne, MorphTo, MorphToMany } from "./relations/index.js";
|
|
4
|
+
import type { GlobalScope } from "./scopes.js";
|
|
5
5
|
export declare abstract class Model<Attributes extends Record<string, any> = Record<string, any>> {
|
|
6
6
|
[key: string]: any;
|
|
7
7
|
/**
|
package/dist/model.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/** biome-ignore-all lint/correctness/noConstructorReturn: <ignore> */
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
|
-
import { castAttribute, serializeForStorage } from "./casts";
|
|
4
|
-
import { getKnex } from "./connection";
|
|
5
|
-
import { DatabaseError } from "./errors";
|
|
6
|
-
import { getDatabaseEventDispatcher } from "./events";
|
|
7
|
-
import { Factory } from "./factory";
|
|
8
|
-
import { ModelQueryBuilder } from "./query-builder";
|
|
9
|
-
import { BelongsTo, BelongsToMany, HasMany, HasOne, MorphedByMany, MorphMany, MorphMap, MorphOne, MorphTo, MorphToMany, } from "./relations";
|
|
10
|
-
import { toCamelCase, toSnakeCase } from "./utils";
|
|
3
|
+
import { castAttribute, serializeForStorage } from "./casts.js";
|
|
4
|
+
import { getKnex } from "./connection.js";
|
|
5
|
+
import { DatabaseError } from "./errors.js";
|
|
6
|
+
import { getDatabaseEventDispatcher } from "./events.js";
|
|
7
|
+
import { Factory } from "./factory.js";
|
|
8
|
+
import { ModelQueryBuilder } from "./query-builder.js";
|
|
9
|
+
import { BelongsTo, BelongsToMany, HasMany, HasOne, MorphedByMany, MorphMany, MorphMap, MorphOne, MorphTo, MorphToMany, } from "./relations/index.js";
|
|
10
|
+
import { toCamelCase, toSnakeCase } from "./utils.js";
|
|
11
11
|
export class Model {
|
|
12
12
|
/**
|
|
13
13
|
* Database table name.
|
|
@@ -285,7 +285,7 @@ export class Model {
|
|
|
285
285
|
* Executes a database transaction.
|
|
286
286
|
*/
|
|
287
287
|
static async transaction(callback) {
|
|
288
|
-
const { transaction: runTrx } = await import("./connection");
|
|
288
|
+
const { transaction: runTrx } = await import("./connection.js");
|
|
289
289
|
return await runTrx(callback);
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
@@ -336,12 +336,15 @@ export class Model {
|
|
|
336
336
|
*/
|
|
337
337
|
static async destroy(id) {
|
|
338
338
|
const knex = getKnex();
|
|
339
|
+
const clientType = knex.client?.config?.client;
|
|
339
340
|
if (this.softDeletes) {
|
|
340
341
|
const col = toSnakeCase(this.deletedAtColumn || "deleted_at");
|
|
341
342
|
const count = await knex(this.table)
|
|
342
343
|
.where(this.primaryKey, id)
|
|
343
344
|
.whereNull(col)
|
|
344
|
-
.update({
|
|
345
|
+
.update({
|
|
346
|
+
[col]: serializeForStorage(new Date(), "datetime", clientType),
|
|
347
|
+
});
|
|
345
348
|
return count > 0;
|
|
346
349
|
}
|
|
347
350
|
const count = await knex(this.table).where(this.primaryKey, id).delete();
|
|
@@ -607,7 +610,18 @@ export class Model {
|
|
|
607
610
|
}
|
|
608
611
|
insertData[col] = serializeForStorage(v, castType, clientType);
|
|
609
612
|
}
|
|
610
|
-
await knex(modelClass.table)
|
|
613
|
+
const insertResult = await knex(modelClass.table)
|
|
614
|
+
.insert(insertData)
|
|
615
|
+
.returning(pk);
|
|
616
|
+
if (!this.getAttribute(pk)) {
|
|
617
|
+
if (Array.isArray(insertResult) && insertResult.length > 0) {
|
|
618
|
+
const first = insertResult[0];
|
|
619
|
+
const returnedId = typeof first === "object" && first !== null ? first[pk] : first;
|
|
620
|
+
if (returnedId !== undefined && returnedId !== null) {
|
|
621
|
+
this.setAttribute(pk, returnedId);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
611
625
|
this.isNew = false;
|
|
612
626
|
this._original = { ...this._attributes };
|
|
613
627
|
await this.fireModelEvent("created");
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServiceProvider } from "@veap/kernel";
|
|
2
|
-
import type { DatabaseConfig } from "./types";
|
|
2
|
+
import type { DatabaseConfig } from "./types.js";
|
|
3
3
|
export interface DatabaseProviderConfig {
|
|
4
4
|
databaseUrl?: string;
|
|
5
5
|
config?: DatabaseConfig;
|
|
@@ -9,4 +9,5 @@ export declare class DatabaseServiceProvider extends ServiceProvider {
|
|
|
9
9
|
constructor(container: any, config?: DatabaseProviderConfig);
|
|
10
10
|
register(): void;
|
|
11
11
|
boot(): Promise<void>;
|
|
12
|
+
shutdown(): Promise<void>;
|
|
12
13
|
}
|
package/dist/provider.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ConfigService,
|
|
1
|
+
import { ConfigService, ServiceProvider } from "@veap/kernel";
|
|
2
2
|
import knex from "knex";
|
|
3
|
-
import { initDatabase, isSqliteDatabase, resolvePostgresSslConfig, resolveSqliteFilename, setKnex, } from "./connection";
|
|
4
|
-
import {
|
|
3
|
+
import { getKnex, initDatabase, isSqliteDatabase, resolvePostgresSslConfig, resolveSqliteFilename, setKnex, } from "./connection.js";
|
|
4
|
+
import { setDatabaseEventDispatcher } from "./events.js";
|
|
5
|
+
import { debug, setDatabaseLogger } from "./logger.js";
|
|
6
|
+
import { DATABASE } from "./tokens.js";
|
|
5
7
|
export class DatabaseServiceProvider extends ServiceProvider {
|
|
6
8
|
config;
|
|
7
9
|
constructor(container, config) {
|
|
@@ -12,13 +14,54 @@ export class DatabaseServiceProvider extends ServiceProvider {
|
|
|
12
14
|
// Port token registration
|
|
13
15
|
}
|
|
14
16
|
async boot() {
|
|
15
|
-
|
|
17
|
+
let configService = null;
|
|
18
|
+
if (this.container.has(ConfigService)) {
|
|
19
|
+
configService = await this.container.resolve(ConfigService);
|
|
20
|
+
}
|
|
21
|
+
else if (this.container.has("ConfigService")) {
|
|
22
|
+
configService = await this.container.resolve("ConfigService");
|
|
23
|
+
}
|
|
16
24
|
const databaseUrl = this.config?.databaseUrl ||
|
|
17
|
-
configService
|
|
25
|
+
configService?.get?.("DATABASE_URL") ||
|
|
18
26
|
process.env.DATABASE_URL ||
|
|
19
27
|
process.env.DATABASE_FILE;
|
|
20
|
-
const isProd = configService
|
|
28
|
+
const isProd = configService?.get?.("NODE_ENV") === "production" ||
|
|
21
29
|
process.env.NODE_ENV === "production";
|
|
30
|
+
// Auto-wire EventDispatcher if bound to container
|
|
31
|
+
if (this.container.has("EventDispatcher")) {
|
|
32
|
+
try {
|
|
33
|
+
const dispatcher = (await this.container.resolve("EventDispatcher"));
|
|
34
|
+
if (dispatcher && typeof dispatcher.publish === "function") {
|
|
35
|
+
setDatabaseEventDispatcher(dispatcher);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Continue without event dispatcher
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Auto-wire Logger if bound to container
|
|
43
|
+
if (this.container.has("LOGGER")) {
|
|
44
|
+
try {
|
|
45
|
+
const logger = (await this.container.resolve("LOGGER"));
|
|
46
|
+
if (logger && typeof logger.info === "function") {
|
|
47
|
+
setDatabaseLogger({
|
|
48
|
+
debug: (ch, msg, ...args) => logger.debug
|
|
49
|
+
? logger.debug(`[${ch}] ${msg}`, ...args)
|
|
50
|
+
: undefined,
|
|
51
|
+
info: (ch, msg, ...args) => logger.info(`[${ch}] ${msg}`, ...args),
|
|
52
|
+
warn: (ch, msg, ...args) => logger.warn
|
|
53
|
+
? logger.warn(`[${ch}] ${msg}`, ...args)
|
|
54
|
+
: console.warn(`[${ch}] ${msg}`, ...args),
|
|
55
|
+
error: (ch, msg, ...args) => logger.error
|
|
56
|
+
? logger.error(`[${ch}] ${msg}`, ...args)
|
|
57
|
+
: console.error(`[${ch}] ${msg}`, ...args),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Continue with default logger
|
|
63
|
+
}
|
|
64
|
+
}
|
|
22
65
|
if (this.config?.config) {
|
|
23
66
|
const instance = initDatabase(this.config.config);
|
|
24
67
|
this.container.register({ token: DATABASE, useValue: instance });
|
|
@@ -32,8 +75,8 @@ export class DatabaseServiceProvider extends ServiceProvider {
|
|
|
32
75
|
const ssl = resolvePostgresSslConfig({
|
|
33
76
|
databaseUrl: resolvedUrl,
|
|
34
77
|
isProd,
|
|
35
|
-
rejectUnauthorizedEnv: configService
|
|
36
|
-
caCert: configService
|
|
78
|
+
rejectUnauthorizedEnv: configService?.get?.("DATABASE_SSL_REJECT_UNAUTHORIZED"),
|
|
79
|
+
caCert: configService?.get?.("DATABASE_SSL_CA"),
|
|
37
80
|
});
|
|
38
81
|
const instance = knex({
|
|
39
82
|
client,
|
|
@@ -55,4 +98,15 @@ export class DatabaseServiceProvider extends ServiceProvider {
|
|
|
55
98
|
useValue: instance,
|
|
56
99
|
});
|
|
57
100
|
}
|
|
101
|
+
async shutdown() {
|
|
102
|
+
try {
|
|
103
|
+
const k = getKnex();
|
|
104
|
+
if (k && typeof k.destroy === "function") {
|
|
105
|
+
await k.destroy();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Ignore if not initialized
|
|
110
|
+
}
|
|
111
|
+
}
|
|
58
112
|
}
|
package/dist/query-builder.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Knex } from "knex";
|
|
2
|
-
import type { Model } from "./model";
|
|
2
|
+
import type { Model } from "./model.js";
|
|
3
|
+
import type { PaginationResult } from "./types.js";
|
|
3
4
|
export declare class ModelQueryBuilder<M extends Model = any> {
|
|
4
5
|
modelClass: any;
|
|
5
6
|
[key: string]: any;
|
|
@@ -65,6 +66,9 @@ export declare class ModelQueryBuilder<M extends Model = any> {
|
|
|
65
66
|
take(count: number): this;
|
|
66
67
|
offset(count: number): this;
|
|
67
68
|
skip(count: number): this;
|
|
69
|
+
groupBy(...columns: any[]): this;
|
|
70
|
+
having(column: any, operatorOrValue?: any, value?: any): this;
|
|
71
|
+
distinct(...columns: any[]): this;
|
|
68
72
|
join(table: string, first: string, operatorOrSecond: string, second?: string): this;
|
|
69
73
|
leftJoin(table: string, first: string, operatorOrSecond: string, second?: string): this;
|
|
70
74
|
/**
|
|
@@ -162,12 +166,8 @@ export declare class ModelQueryBuilder<M extends Model = any> {
|
|
|
162
166
|
/**
|
|
163
167
|
* Paginates results.
|
|
164
168
|
*/
|
|
165
|
-
paginate(page?: number, perPage?: number): Promise<{
|
|
166
|
-
data: M[];
|
|
167
|
-
total: number;
|
|
169
|
+
paginate(page?: number, perPage?: number): Promise<PaginationResult<M> & {
|
|
168
170
|
page: number;
|
|
169
|
-
perPage: number;
|
|
170
|
-
lastPage: number;
|
|
171
171
|
}>;
|
|
172
172
|
/**
|
|
173
173
|
* Bulk updates matching records.
|
package/dist/query-builder.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { serializeForStorage } from "./casts";
|
|
2
|
-
import { getKnex } from "./connection";
|
|
3
|
-
import { DatabaseError } from "./errors";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { toCamelCase, toSnakeCase } from "./utils";
|
|
1
|
+
import { serializeForStorage } from "./casts.js";
|
|
2
|
+
import { getKnex } from "./connection.js";
|
|
3
|
+
import { DatabaseError } from "./errors.js";
|
|
4
|
+
import { eagerLoadRelations } from "./relations/eager-loader.js";
|
|
5
|
+
import { BelongsTo, BelongsToMany, MorphedByMany, MorphMany, MorphOne, MorphToMany, } from "./relations/index.js";
|
|
6
|
+
import { toCamelCase, toSnakeCase } from "./utils.js";
|
|
7
7
|
export class ModelQueryBuilder {
|
|
8
8
|
modelClass;
|
|
9
9
|
knexBuilder;
|
|
@@ -47,6 +47,14 @@ export class ModelQueryBuilder {
|
|
|
47
47
|
: result;
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
// 3. Delegate to Knex query builder if method exists (e.g. groupBy, having, distinct, joinRaw)
|
|
51
|
+
if (target.knexBuilder &&
|
|
52
|
+
typeof target.knexBuilder[prop] === "function") {
|
|
53
|
+
return (...args) => {
|
|
54
|
+
const result = target.knexBuilder[prop](...args);
|
|
55
|
+
return result === target.knexBuilder ? receiver : result;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
return Reflect.get(target, prop, receiver);
|
|
52
60
|
},
|
|
@@ -270,6 +278,30 @@ export class ModelQueryBuilder {
|
|
|
270
278
|
skip(count) {
|
|
271
279
|
return this.offset(count);
|
|
272
280
|
}
|
|
281
|
+
groupBy(...columns) {
|
|
282
|
+
const converted = columns.map((col) => typeof col === "string" ? toSnakeCase(col) : col);
|
|
283
|
+
this.knexBuilder.groupBy(...converted);
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
having(column, operatorOrValue, value) {
|
|
287
|
+
if (value === undefined) {
|
|
288
|
+
if (operatorOrValue === undefined) {
|
|
289
|
+
this.knexBuilder.having(column);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
this.knexBuilder.having(column, "=", operatorOrValue);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
this.knexBuilder.having(column, operatorOrValue, value);
|
|
297
|
+
}
|
|
298
|
+
return this;
|
|
299
|
+
}
|
|
300
|
+
distinct(...columns) {
|
|
301
|
+
const converted = columns.map((col) => typeof col === "string" ? toSnakeCase(col) : col);
|
|
302
|
+
this.knexBuilder.distinct(...converted);
|
|
303
|
+
return this;
|
|
304
|
+
}
|
|
273
305
|
join(table, first, operatorOrSecond, second) {
|
|
274
306
|
if (second === undefined) {
|
|
275
307
|
this.knexBuilder.join(table, first, operatorOrSecond);
|
|
@@ -646,6 +678,7 @@ export class ModelQueryBuilder {
|
|
|
646
678
|
data,
|
|
647
679
|
total,
|
|
648
680
|
page,
|
|
681
|
+
currentPage: page,
|
|
649
682
|
perPage,
|
|
650
683
|
lastPage,
|
|
651
684
|
};
|
|
@@ -654,6 +687,7 @@ export class ModelQueryBuilder {
|
|
|
654
687
|
* Bulk updates matching records.
|
|
655
688
|
*/
|
|
656
689
|
async update(attributes) {
|
|
690
|
+
this.applyGlobalScopes();
|
|
657
691
|
const converted = {};
|
|
658
692
|
const casts = this.modelClass?.casts || {};
|
|
659
693
|
const knex = getKnex();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class BelongsToMany<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
pivotTable: string;
|
|
6
6
|
foreignPivotKey: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class BelongsTo<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
query(): ModelQueryBuilder<Related>;
|
|
6
6
|
get(): Promise<Related | null>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseError } from "../errors";
|
|
1
|
+
import { DatabaseError } from "../errors.js";
|
|
2
2
|
/**
|
|
3
3
|
* Loads relations onto an array of model instances in bulk queries, avoiding N+1.
|
|
4
4
|
*/
|
|
@@ -11,6 +11,8 @@ export async function eagerLoadRelations(models, relations) {
|
|
|
11
11
|
for (const rel of relations) {
|
|
12
12
|
const parts = rel.split(".");
|
|
13
13
|
const head = parts[0];
|
|
14
|
+
if (!head)
|
|
15
|
+
continue;
|
|
14
16
|
const tail = parts.slice(1).join(".");
|
|
15
17
|
if (!tree[head]) {
|
|
16
18
|
tree[head] = [];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class HasMany<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
query(): ModelQueryBuilder<Related>;
|
|
6
6
|
get(): Promise<Related[]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class HasOne<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
query(): ModelQueryBuilder<Related>;
|
|
6
6
|
get(): Promise<Related | null>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export * from "./belongs-to";
|
|
2
|
-
export * from "./belongs-to-many";
|
|
3
|
-
export * from "./eager-loader";
|
|
4
|
-
export * from "./has-many";
|
|
5
|
-
export * from "./has-one";
|
|
6
|
-
export * from "./morph-many";
|
|
7
|
-
export * from "./morph-map";
|
|
8
|
-
export * from "./morph-one";
|
|
9
|
-
export * from "./morph-to";
|
|
10
|
-
export * from "./morph-to-many";
|
|
11
|
-
export * from "./relation";
|
|
1
|
+
export * from "./belongs-to.js";
|
|
2
|
+
export * from "./belongs-to-many.js";
|
|
3
|
+
export * from "./eager-loader.js";
|
|
4
|
+
export * from "./has-many.js";
|
|
5
|
+
export * from "./has-one.js";
|
|
6
|
+
export * from "./morph-many.js";
|
|
7
|
+
export * from "./morph-map.js";
|
|
8
|
+
export * from "./morph-one.js";
|
|
9
|
+
export * from "./morph-to.js";
|
|
10
|
+
export * from "./morph-to-many.js";
|
|
11
|
+
export * from "./relation.js";
|
package/dist/relations/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export * from "./belongs-to";
|
|
2
|
-
export * from "./belongs-to-many";
|
|
3
|
-
export * from "./eager-loader";
|
|
4
|
-
export * from "./has-many";
|
|
5
|
-
export * from "./has-one";
|
|
6
|
-
export * from "./morph-many";
|
|
7
|
-
export * from "./morph-map";
|
|
8
|
-
export * from "./morph-one";
|
|
9
|
-
export * from "./morph-to";
|
|
10
|
-
export * from "./morph-to-many";
|
|
11
|
-
export * from "./relation";
|
|
1
|
+
export * from "./belongs-to.js";
|
|
2
|
+
export * from "./belongs-to-many.js";
|
|
3
|
+
export * from "./eager-loader.js";
|
|
4
|
+
export * from "./has-many.js";
|
|
5
|
+
export * from "./has-one.js";
|
|
6
|
+
export * from "./morph-many.js";
|
|
7
|
+
export * from "./morph-map.js";
|
|
8
|
+
export * from "./morph-one.js";
|
|
9
|
+
export * from "./morph-to.js";
|
|
10
|
+
export * from "./morph-to-many.js";
|
|
11
|
+
export * from "./relation.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class MorphMany<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
morphName: string;
|
|
6
6
|
typeColumn: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class MorphOne<Parent extends Model = any, Related extends Model = any> extends Relation<Parent, Related> {
|
|
5
5
|
morphName: string;
|
|
6
6
|
typeColumn: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
/**
|
|
5
5
|
* MorphToMany represents a many-to-many polymorphic relation where the parent
|
|
6
6
|
* owns the polymorphic side of the pivot table (e.g. BlogPost -> tags via taggables).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getKnex } from "../connection";
|
|
2
|
-
import { MorphMap } from "./morph-map";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import { getKnex } from "../connection.js";
|
|
2
|
+
import { MorphMap } from "./morph-map.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
/**
|
|
5
5
|
* MorphToMany represents a many-to-many polymorphic relation where the parent
|
|
6
6
|
* owns the polymorphic side of the pivot table (e.g. BlogPost -> tags via taggables).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export declare class MorphTo<Child extends Model = any, Parent extends Model = any> extends Relation<Child, Parent> {
|
|
5
5
|
morphName: string;
|
|
6
6
|
typeColumn: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DatabaseError } from "../errors";
|
|
2
|
-
import { MorphMap } from "./morph-map";
|
|
3
|
-
import { Relation } from "./relation";
|
|
1
|
+
import { DatabaseError } from "../errors.js";
|
|
2
|
+
import { MorphMap } from "./morph-map.js";
|
|
3
|
+
import { Relation } from "./relation.js";
|
|
4
4
|
export class MorphTo extends Relation {
|
|
5
5
|
morphName;
|
|
6
6
|
typeColumn;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Model } from "../model";
|
|
2
|
-
import type { ModelQueryBuilder } from "../query-builder";
|
|
1
|
+
import type { Model } from "../model.js";
|
|
2
|
+
import type { ModelQueryBuilder } from "../query-builder.js";
|
|
3
3
|
export declare abstract class Relation<Parent extends Model = any, Related extends Model = any> {
|
|
4
4
|
parent: Parent;
|
|
5
5
|
related: any;
|
package/dist/scopes.d.ts
CHANGED
package/dist/seeder.js
CHANGED
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Token } from "@veap/kernel";
|
|
2
|
+
import type { Knex } from "knex";
|
|
3
|
+
/**
|
|
4
|
+
* IoC Token for primary Knex database connection instance.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DATABASE: Token<Knex>;
|
|
7
|
+
/**
|
|
8
|
+
* IoC Token for application database migrations array.
|
|
9
|
+
*/
|
|
10
|
+
export declare const APP_MIGRATIONS: Token<any[]>;
|
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IoC Token for primary Knex database connection instance.
|
|
3
|
+
*/
|
|
4
|
+
export const DATABASE = Symbol.for("veap:kernel:database");
|
|
5
|
+
/**
|
|
6
|
+
* IoC Token for application database migrations array.
|
|
7
|
+
*/
|
|
8
|
+
export const APP_MIGRATIONS = Symbol.for("veap:kernel:app-migrations");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veap/database",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Eloquent-like Active Record ORM powered by Knex with AsyncLocalStorage transactions",
|
|
5
5
|
"bugs": "https://github.com/veapjs/veap-database/issues",
|
|
6
6
|
"repository": {
|
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
"types": "./dist/index.d.ts",
|
|
17
17
|
"default": "./dist/index.js"
|
|
18
18
|
},
|
|
19
|
+
"./migrations": {
|
|
20
|
+
"types": "./dist/migrations/index.d.ts",
|
|
21
|
+
"default": "./dist/migrations/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./relations": {
|
|
24
|
+
"types": "./dist/relations/index.d.ts",
|
|
25
|
+
"default": "./dist/relations/index.js"
|
|
26
|
+
},
|
|
19
27
|
"./package.json": "./package.json"
|
|
20
28
|
},
|
|
21
29
|
"files": [
|
|
@@ -28,7 +36,7 @@
|
|
|
28
36
|
"test": "vitest run"
|
|
29
37
|
},
|
|
30
38
|
"dependencies": {
|
|
31
|
-
"@veap/kernel": "^0.1.
|
|
39
|
+
"@veap/kernel": "^0.1.1",
|
|
32
40
|
"better-sqlite3": "^13.0.3",
|
|
33
41
|
"knex": "^3.3.0"
|
|
34
42
|
},
|