arckode-framework 1.1.1 → 1.1.2
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/adapters/sqlite.ts +22 -27
- package/kernel/framework.ts +18 -1
- package/package.json +1 -6
package/adapters/sqlite.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// adapters/sqlite.ts — Adapter SQLite
|
|
2
|
-
// Responsabilidad ÚNICA: traducir llamadas de DbAdapter a
|
|
1
|
+
// adapters/sqlite.ts — Adapter SQLite (bun:sqlite)
|
|
2
|
+
// Responsabilidad ÚNICA: traducir llamadas de DbAdapter a bun:sqlite
|
|
3
3
|
// SOLID: implementa DbAdapter, puede reemplazarse por PostgresAdapter sin cambiar el ORM
|
|
4
4
|
|
|
5
|
-
import Database from '
|
|
5
|
+
import { Database } from 'bun:sqlite'
|
|
6
6
|
import type { DbAdapter } from '../kernel/framework'
|
|
7
7
|
|
|
8
8
|
interface SqliteConfig {
|
|
@@ -11,7 +11,6 @@ interface SqliteConfig {
|
|
|
11
11
|
foreignKeys?: boolean
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// Configuración con valores por defecto
|
|
15
14
|
const DEFAULT_CONFIG: SqliteConfig = {
|
|
16
15
|
path: './data/db.sqlite',
|
|
17
16
|
wal: true,
|
|
@@ -19,7 +18,7 @@ const DEFAULT_CONFIG: SqliteConfig = {
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export class SqliteAdapter implements DbAdapter {
|
|
22
|
-
private db!: Database
|
|
21
|
+
private db!: Database
|
|
23
22
|
private config: SqliteConfig
|
|
24
23
|
|
|
25
24
|
constructor(config?: Partial<SqliteConfig>) {
|
|
@@ -29,19 +28,21 @@ export class SqliteAdapter implements DbAdapter {
|
|
|
29
28
|
async connect(): Promise<void> {
|
|
30
29
|
this.db = new Database(this.config.path)
|
|
31
30
|
|
|
32
|
-
if (this.config.wal) this.db.
|
|
33
|
-
if (this.config.foreignKeys) this.db.
|
|
31
|
+
if (this.config.wal) this.db.exec('PRAGMA journal_mode = WAL')
|
|
32
|
+
if (this.config.foreignKeys) this.db.exec('PRAGMA foreign_keys = ON')
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
query(sql: string, params: unknown[] = []): Promise<unknown[]> {
|
|
37
|
-
const stmt = this.db.
|
|
38
|
-
const rows = params.length > 0 ? stmt.all(...params) : stmt.all()
|
|
39
|
-
return Promise.resolve(rows)
|
|
36
|
+
const stmt = this.db.query(sql)
|
|
37
|
+
const rows = params.length > 0 ? stmt.all(...(params as Parameters<typeof stmt.all>)) : stmt.all()
|
|
38
|
+
return Promise.resolve(rows as unknown[])
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
run(sql: string, params: unknown[] = []): Promise<{ changes: number; lastId?: string }> {
|
|
43
|
-
const stmt = this.db.
|
|
44
|
-
const result = params.length > 0
|
|
42
|
+
const stmt = this.db.query(sql)
|
|
43
|
+
const result = params.length > 0
|
|
44
|
+
? stmt.run(...(params as Parameters<typeof stmt.run>))
|
|
45
|
+
: stmt.run()
|
|
45
46
|
return Promise.resolve({
|
|
46
47
|
changes: result.changes,
|
|
47
48
|
lastId: result.lastInsertRowid ? String(result.lastInsertRowid) : undefined,
|
|
@@ -49,21 +50,15 @@ export class SqliteAdapter implements DbAdapter {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
async transaction<T>(fn: (adapter: DbAdapter) => Promise<T>): Promise<T> {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
})
|
|
62
|
-
.catch((err) => {
|
|
63
|
-
try { this.db.exec('ROLLBACK') } catch { /* ya hizo rollback */ }
|
|
64
|
-
reject(err)
|
|
65
|
-
})
|
|
66
|
-
})
|
|
53
|
+
this.db.exec('BEGIN')
|
|
54
|
+
try {
|
|
55
|
+
const result = await fn(this)
|
|
56
|
+
this.db.exec('COMMIT')
|
|
57
|
+
return result
|
|
58
|
+
} catch (err) {
|
|
59
|
+
try { this.db.exec('ROLLBACK') } catch { /* ya hizo rollback */ }
|
|
60
|
+
throw err
|
|
61
|
+
}
|
|
67
62
|
}
|
|
68
63
|
|
|
69
64
|
close(): Promise<void> {
|
package/kernel/framework.ts
CHANGED
|
@@ -896,6 +896,23 @@ export class ORM {
|
|
|
896
896
|
} catch {
|
|
897
897
|
// Error esperado: la columna ya existe — ignorar
|
|
898
898
|
}
|
|
899
|
+
|
|
900
|
+
// 3c. Corregir drift de nullability: si el modelo dice nullable pero la columna es NOT NULL, quitarlo
|
|
901
|
+
// Solo PostgreSQL soporta ALTER COLUMN ... DROP NOT NULL de forma confiable
|
|
902
|
+
if (field.nullable === true) {
|
|
903
|
+
try {
|
|
904
|
+
await this.db.run(`ALTER TABLE ${def.table} ALTER COLUMN ${name} DROP NOT NULL`)
|
|
905
|
+
} catch { /* SQLite no soporta esto — ignorar */ }
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// 3b. Agregar columnas de timestamps/softDelete si el modelo las requiere pero no existen aún
|
|
910
|
+
if (def.timestamps) {
|
|
911
|
+
try { await this.db.run(`ALTER TABLE ${def.table} ADD COLUMN createdAt TEXT`) } catch { /* ya existe */ }
|
|
912
|
+
try { await this.db.run(`ALTER TABLE ${def.table} ADD COLUMN updatedAt TEXT`) } catch { /* ya existe */ }
|
|
913
|
+
}
|
|
914
|
+
if (def.softDelete) {
|
|
915
|
+
try { await this.db.run(`ALTER TABLE ${def.table} ADD COLUMN deletedAt TEXT`) } catch { /* ya existe */ }
|
|
899
916
|
}
|
|
900
917
|
|
|
901
918
|
// 4. Detectar drift de schema: columnas en la BD que ya no están en el modelo
|
|
@@ -1602,7 +1619,7 @@ export class Auth {
|
|
|
1602
1619
|
|
|
1603
1620
|
createRefreshToken(payload: { id: string; role: string }): string {
|
|
1604
1621
|
const token = this.jwt.sign(
|
|
1605
|
-
{ id: payload.id, role: payload.role, type: 'refresh' },
|
|
1622
|
+
{ id: payload.id, role: payload.role, type: 'refresh', jti: crypto.randomUUID() },
|
|
1606
1623
|
this.refreshSecret,
|
|
1607
1624
|
this.refreshExpiresIn,
|
|
1608
1625
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arckode-framework",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "AI-first TypeScript/Bun framework. Modular, SOLID, zero magic. The AI reads the composition root and knows everything.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./kernel/framework.ts",
|
|
@@ -58,16 +58,12 @@
|
|
|
58
58
|
"jsonwebtoken": "^9.0.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"better-sqlite3": ">=11.0.0",
|
|
62
61
|
"mysql2": ">=3.0.0",
|
|
63
62
|
"pg": "^8.0.0",
|
|
64
63
|
"redis": ">=4.0.0",
|
|
65
64
|
"nodemailer": ">=6.0.0"
|
|
66
65
|
},
|
|
67
66
|
"peerDependenciesMeta": {
|
|
68
|
-
"better-sqlite3": {
|
|
69
|
-
"optional": true
|
|
70
|
-
},
|
|
71
67
|
"mysql2": {
|
|
72
68
|
"optional": true
|
|
73
69
|
},
|
|
@@ -82,7 +78,6 @@
|
|
|
82
78
|
}
|
|
83
79
|
},
|
|
84
80
|
"devDependencies": {
|
|
85
|
-
"@types/better-sqlite3": "^7.6.12",
|
|
86
81
|
"@types/jsonwebtoken": "^9.0.7",
|
|
87
82
|
"@types/nodemailer": "^6.4.0",
|
|
88
83
|
"@types/pg": "^8.11.0",
|