@zhin.js/database 1.0.44 → 1.0.47
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 +7 -4
- package/CHANGELOG.md +0 -287
- package/src/base/database.ts +0 -272
- package/src/base/dialect.ts +0 -89
- package/src/base/index.ts +0 -6
- package/src/base/model.ts +0 -329
- package/src/base/query-classes.ts +0 -625
- package/src/base/thenable.ts +0 -55
- package/src/base/transaction.ts +0 -213
- package/src/dialects/memory.ts +0 -882
- package/src/dialects/mongodb.ts +0 -535
- package/src/dialects/mysql.ts +0 -286
- package/src/dialects/pg.ts +0 -284
- package/src/dialects/redis.ts +0 -600
- package/src/dialects/sqlite.ts +0 -317
- package/src/index.ts +0 -19
- package/src/migration.ts +0 -547
- package/src/registry.ts +0 -59
- package/src/type/document/database.ts +0 -284
- package/src/type/document/model.ts +0 -87
- package/src/type/keyvalue/database.ts +0 -262
- package/src/type/keyvalue/model.ts +0 -339
- package/src/type/related/database.ts +0 -674
- package/src/type/related/model.ts +0 -884
- package/src/types.ts +0 -918
- package/tests/database.test.ts +0 -1750
- package/tests/dialects.test.ts +0 -147
- package/tests/migration.test.ts +0 -73
- package/tsconfig.json +0 -24
package/tests/dialects.test.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { createRequire } from 'node:module'
|
|
2
|
-
import { describe, it, expect, beforeEach } from 'vitest'
|
|
3
|
-
|
|
4
|
-
const require = createRequire(import.meta.url)
|
|
5
|
-
let sqliteAvailable = false
|
|
6
|
-
try {
|
|
7
|
-
const { DatabaseSync } = require('node:sqlite')
|
|
8
|
-
const db = new DatabaseSync(':memory:')
|
|
9
|
-
db.close()
|
|
10
|
-
sqliteAvailable = true
|
|
11
|
-
} catch {
|
|
12
|
-
// Node 内置 SQLite 需要 Node.js 22.5+
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
describe('Database Dialects', () => {
|
|
16
|
-
describe('Memory Dialect', () => {
|
|
17
|
-
it('should export MemoryDialect', async () => {
|
|
18
|
-
const { MemoryDialect } = await import('../src/dialects/memory')
|
|
19
|
-
expect(MemoryDialect).toBeDefined()
|
|
20
|
-
expect(typeof MemoryDialect).toBe('function')
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
describe('MySQL Dialect', () => {
|
|
25
|
-
it('should export MySQLDialect', async () => {
|
|
26
|
-
const { MySQLDialect } = await import('../src/dialects/mysql')
|
|
27
|
-
expect(MySQLDialect).toBeDefined()
|
|
28
|
-
expect(typeof MySQLDialect).toBe('function')
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
describe('PostgreSQL Dialect', () => {
|
|
33
|
-
it('should export PostgreSQLDialect', async () => {
|
|
34
|
-
const { PostgreSQLDialect } = await import('../src/dialects/pg')
|
|
35
|
-
expect(PostgreSQLDialect).toBeDefined()
|
|
36
|
-
expect(typeof PostgreSQLDialect).toBe('function')
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
describe('MongoDB Dialect', () => {
|
|
41
|
-
it('should export MongoDBDialect', async () => {
|
|
42
|
-
const { MongoDBDialect } = await import('../src/dialects/mongodb')
|
|
43
|
-
expect(MongoDBDialect).toBeDefined()
|
|
44
|
-
expect(typeof MongoDBDialect).toBe('function')
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
describe('Redis Dialect', () => {
|
|
49
|
-
it('should export RedisDialect', async () => {
|
|
50
|
-
const { RedisDialect } = await import('../src/dialects/redis')
|
|
51
|
-
expect(RedisDialect).toBeDefined()
|
|
52
|
-
expect(typeof RedisDialect).toBe('function')
|
|
53
|
-
})
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
describe('SQLite Dialect', () => {
|
|
57
|
-
it('should export SQLiteDialect', async () => {
|
|
58
|
-
const { SQLiteDialect } = await import('../src/dialects/sqlite')
|
|
59
|
-
expect(SQLiteDialect).toBeDefined()
|
|
60
|
-
expect(typeof SQLiteDialect).toBe('function')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('processFieldValue (JSON parsing)', () => {
|
|
64
|
-
let dialect: any
|
|
65
|
-
|
|
66
|
-
beforeEach(async () => {
|
|
67
|
-
const { SQLiteDialect } = await import('../src/dialects/sqlite')
|
|
68
|
-
dialect = new SQLiteDialect({ filename: ':memory:' } as any)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
// 通过 processRowData 间接测试 processFieldValue
|
|
72
|
-
function processValue(value: any): any {
|
|
73
|
-
// processRowData 会对每个字段调用 processFieldValue
|
|
74
|
-
const result = (dialect as any).processRowData({ field: value })
|
|
75
|
-
return result.field
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
it('should parse unquoted JSON object string', () => {
|
|
79
|
-
const result = processValue('{"key":"value","num":42}')
|
|
80
|
-
expect(result).toEqual({ key: 'value', num: 42 })
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('should parse unquoted JSON array string', () => {
|
|
84
|
-
const result = processValue('[{"role":"user","content":"hi"},{"role":"assistant","content":"hello"}]')
|
|
85
|
-
expect(result).toEqual([
|
|
86
|
-
{ role: 'user', content: 'hi' },
|
|
87
|
-
{ role: 'assistant', content: 'hello' },
|
|
88
|
-
])
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('should parse single-quoted JSON string', () => {
|
|
92
|
-
const result = processValue("'{\"x\":1}'")
|
|
93
|
-
expect(result).toEqual({ x: 1 })
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('should parse double-quoted JSON string', () => {
|
|
97
|
-
const result = processValue('"[1,2,3]"')
|
|
98
|
-
expect(result).toEqual([1, 2, 3])
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('should leave plain text strings unchanged', () => {
|
|
102
|
-
const result = processValue('hello world')
|
|
103
|
-
expect(result).toBe('hello world')
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('should handle invalid JSON gracefully (unquoted)', () => {
|
|
107
|
-
const result = processValue('{invalid json}')
|
|
108
|
-
expect(result).toBe('{invalid json}')
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('should handle empty JSON object string', () => {
|
|
112
|
-
const result = processValue('{}')
|
|
113
|
-
expect(result).toEqual({})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it('should handle empty JSON array string', () => {
|
|
117
|
-
const result = processValue('[]')
|
|
118
|
-
expect(result).toEqual([])
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('should return non-string values as-is', () => {
|
|
122
|
-
expect(processValue(42)).toBe(42)
|
|
123
|
-
expect(processValue(null)).toBe(null)
|
|
124
|
-
expect(processValue(undefined)).toBe(undefined)
|
|
125
|
-
expect(processValue(true)).toBe(true)
|
|
126
|
-
})
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
describe.skipIf(!sqliteAvailable)('bind params (JSON object)', () => {
|
|
130
|
-
it('should INSERT plain object as JSON text and read back as object', async () => {
|
|
131
|
-
const { SQLiteDialect } = await import('../src/dialects/sqlite')
|
|
132
|
-
const dialect = new SQLiteDialect({ filename: ':memory:' } as any)
|
|
133
|
-
await dialect.connect()
|
|
134
|
-
await dialect.query('CREATE TABLE "github_events" ("id" INTEGER PRIMARY KEY, "payload" TEXT)')
|
|
135
|
-
const payload = { repository: { full_name: 'o/r' }, zen: 'keep it simple' }
|
|
136
|
-
await dialect.query(
|
|
137
|
-
'INSERT INTO "github_events" ("id", "payload") VALUES (?, ?)',
|
|
138
|
-
[1, payload],
|
|
139
|
-
)
|
|
140
|
-
const rows = (await dialect.query('SELECT "id", "payload" FROM "github_events"')) as any[]
|
|
141
|
-
expect(rows[0].id).toBe(1)
|
|
142
|
-
expect(rows[0].payload).toEqual(payload)
|
|
143
|
-
await dialect.disconnect()
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
})
|
package/tests/migration.test.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration 工具函数测试
|
|
3
|
-
* 测试 generateReverseOperations 逻辑
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, expect } from 'vitest';
|
|
6
|
-
import type { MigrationOperation, Column } from '../src/types.js';
|
|
7
|
-
import { generateReverseOperations } from '../src/migration.js';
|
|
8
|
-
|
|
9
|
-
describe('generateReverseOperations', () => {
|
|
10
|
-
it('createTable 应反转为 dropTable', () => {
|
|
11
|
-
const ops: MigrationOperation[] = [
|
|
12
|
-
{ type: 'createTable', tableName: 'users', columns: { id: { type: 'integer' } } },
|
|
13
|
-
];
|
|
14
|
-
const reversed = generateReverseOperations(ops);
|
|
15
|
-
expect(reversed).toEqual([{ type: 'dropTable', tableName: 'users' }]);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('addColumn 应反转为 dropColumn', () => {
|
|
19
|
-
const ops: MigrationOperation[] = [
|
|
20
|
-
{ type: 'addColumn', tableName: 'users', columnName: 'email', column: { type: 'text' } },
|
|
21
|
-
];
|
|
22
|
-
const reversed = generateReverseOperations(ops);
|
|
23
|
-
expect(reversed).toEqual([{ type: 'dropColumn', tableName: 'users', columnName: 'email' }]);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('addIndex 应反转为 dropIndex', () => {
|
|
27
|
-
const ops: MigrationOperation[] = [
|
|
28
|
-
{ type: 'addIndex', tableName: 'users', indexName: 'idx_email', columns: ['email'] },
|
|
29
|
-
];
|
|
30
|
-
const reversed = generateReverseOperations(ops);
|
|
31
|
-
expect(reversed).toEqual([{ type: 'dropIndex', tableName: 'users', indexName: 'idx_email' }]);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('renameColumn 应反转列名', () => {
|
|
35
|
-
const ops: MigrationOperation[] = [
|
|
36
|
-
{ type: 'renameColumn', tableName: 'users', oldName: 'name', newName: 'full_name' },
|
|
37
|
-
];
|
|
38
|
-
const reversed = generateReverseOperations(ops);
|
|
39
|
-
expect(reversed).toEqual([{ type: 'renameColumn', tableName: 'users', oldName: 'full_name', newName: 'name' }]);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('多个操作应按逆序反转', () => {
|
|
43
|
-
const ops: MigrationOperation[] = [
|
|
44
|
-
{ type: 'createTable', tableName: 'posts', columns: { id: { type: 'integer' } } },
|
|
45
|
-
{ type: 'addColumn', tableName: 'posts', columnName: 'title', column: { type: 'text' } },
|
|
46
|
-
];
|
|
47
|
-
const reversed = generateReverseOperations(ops);
|
|
48
|
-
expect(reversed).toHaveLength(2);
|
|
49
|
-
expect(reversed[0]).toEqual({ type: 'dropColumn', tableName: 'posts', columnName: 'title' });
|
|
50
|
-
expect(reversed[1]).toEqual({ type: 'dropTable', tableName: 'posts' });
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('dropTable 应抛出错误', () => {
|
|
54
|
-
const ops: MigrationOperation[] = [
|
|
55
|
-
{ type: 'dropTable', tableName: 'users' },
|
|
56
|
-
];
|
|
57
|
-
expect(() => generateReverseOperations(ops)).toThrow('Cannot auto-reverse');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('dropColumn 应抛出错误', () => {
|
|
61
|
-
const ops: MigrationOperation[] = [
|
|
62
|
-
{ type: 'dropColumn', tableName: 'users', columnName: 'email' },
|
|
63
|
-
];
|
|
64
|
-
expect(() => generateReverseOperations(ops)).toThrow('Cannot auto-reverse');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('query 应抛出错误', () => {
|
|
68
|
-
const ops: MigrationOperation[] = [
|
|
69
|
-
{ type: 'query', sql: 'DROP TABLE users' },
|
|
70
|
-
];
|
|
71
|
-
expect(() => generateReverseOperations(ops)).toThrow('Cannot auto-reverse raw query');
|
|
72
|
-
});
|
|
73
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"outDir": "./lib",
|
|
7
|
-
"rootDir": "./src",
|
|
8
|
-
"strict": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"resolveJsonModule": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
"allowSyntheticDefaultImports": true,
|
|
15
|
-
"experimentalDecorators": true,
|
|
16
|
-
"emitDecoratorMetadata": true,
|
|
17
|
-
"declaration": true,
|
|
18
|
-
"declarationMap": true,
|
|
19
|
-
"sourceMap": true,
|
|
20
|
-
"verbatimModuleSyntax": false
|
|
21
|
-
},
|
|
22
|
-
"include": ["src/**/*"],
|
|
23
|
-
"exclude": ["lib", "node_modules"]
|
|
24
|
-
}
|