admindb 2.1.0 → 2.2.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 +41 -12
- package/dist/app.d.ts +1 -69
- package/dist/app.js +3 -30
- package/dist/auth/config.d.ts +1 -19
- package/dist/auth/config.js +0 -26
- package/dist/auth/crypto.d.ts +1 -27
- package/dist/auth/crypto.js +1 -26
- package/dist/auth/index.d.ts +1 -5
- package/dist/auth/index.js +0 -1
- package/dist/auth/middleware.d.ts +1 -14
- package/dist/auth/middleware.js +0 -15
- package/dist/auth/routes.d.ts +1 -7
- package/dist/auth/routes.js +0 -8
- package/dist/auth/types.d.ts +1 -35
- package/dist/auth/types.js +1 -5
- package/dist/cli/args.d.ts +1 -45
- package/dist/cli/args.js +3 -11
- package/dist/cli/config.d.ts +1 -56
- package/dist/cli/config.js +0 -5
- package/dist/cli/index.d.ts +1 -4
- package/dist/cli/index.js +0 -1
- package/dist/cli/runner.d.ts +1 -1
- package/dist/cli/runner.js +6 -17
- package/dist/cli.d.ts +1 -2
- package/dist/cli.js +0 -1
- package/dist/data/chain.d.ts +1 -0
- package/dist/data/chain.js +707 -0
- package/dist/data/datasets.d.ts +1 -17
- package/dist/data/datasets.js +0 -4
- package/dist/data/detector.d.ts +1 -30
- package/dist/data/detector.js +53 -14
- package/dist/data/engine.d.ts +1 -10
- package/dist/data/engine.js +82 -48
- package/dist/data/index.d.ts +1 -5
- package/dist/data/index.js +1 -1
- package/dist/data/strategies.d.ts +1 -30
- package/dist/data/strategies.js +4 -8
- package/dist/data/types.d.ts +1 -73
- package/dist/data/types.js +0 -3
- package/dist/db/database.d.ts +1 -119
- package/dist/db/database.js +20 -14
- package/dist/db/export.d.ts +1 -12
- package/dist/db/export.js +54 -6
- package/dist/db/filters.d.ts +1 -22
- package/dist/db/filters.js +0 -16
- package/dist/db/index.d.ts +1 -8
- package/dist/db/index.js +0 -1
- package/dist/db/introspection.d.ts +1 -6
- package/dist/db/introspection.js +0 -5
- package/dist/db/manager.d.ts +1 -81
- package/dist/db/manager.js +13 -59
- package/dist/db/migrations.d.ts +1 -5
- package/dist/db/migrations.js +2 -5
- package/dist/db/postgres.d.ts +1 -85
- package/dist/db/postgres.js +21 -31
- package/dist/db/types.d.ts +1 -206
- package/dist/db/types.js +0 -1
- package/dist/index.d.ts +1 -23
- package/dist/index.js +0 -14
- package/dist/public/css/app.css +1 -1
- package/dist/public/js/api.js +1 -47
- package/dist/public/js/app.js +1 -262
- package/dist/public/js/browse.js +1 -1371
- package/dist/public/js/common.js +1 -0
- package/dist/public/js/databases.js +1 -235
- package/dist/public/js/designer.js +1 -258
- package/dist/public/js/forms.js +1 -826
- package/dist/public/js/home.js +1 -0
- package/dist/public/js/inspector.js +1 -638
- package/dist/public/js/query.js +1 -322
- package/dist/public/js/schema.js +1 -447
- package/dist/public/js/seed.js +1 -1090
- package/dist/routes/api/erd.d.ts +1 -0
- package/dist/routes/api/erd.js +50 -0
- package/dist/routes/api/helpers.d.ts +1 -42
- package/dist/routes/api/helpers.js +33 -3
- package/dist/routes/api/import-export.d.ts +1 -3
- package/dist/routes/api/import-export.js +0 -2
- package/dist/routes/api/index.d.ts +1 -4
- package/dist/routes/api/index.js +15 -4
- package/dist/routes/api/query.d.ts +1 -3
- package/dist/routes/api/query.js +13 -11
- package/dist/routes/api/rows.d.ts +1 -3
- package/dist/routes/api/rows.js +0 -11
- package/dist/routes/api/seed.d.ts +1 -3
- package/dist/routes/api/seed.js +79 -8
- package/dist/routes/api/tables.d.ts +1 -3
- package/dist/routes/api/tables.js +77 -6
- package/dist/routes/databases.d.ts +1 -26
- package/dist/routes/databases.js +1 -3
- package/dist/routes/index.d.ts +1 -3
- package/dist/routes/index.js +0 -1
- package/dist/routes/pages.d.ts +1 -9
- package/dist/routes/pages.js +18 -11
- package/dist/serverless.d.ts +1 -40
- package/dist/serverless.js +3 -39
- package/dist/sql/classifier.d.ts +1 -19
- package/dist/sql/classifier.js +0 -13
- package/dist/sql/error-analyzer.d.ts +1 -0
- package/dist/sql/error-analyzer.js +550 -0
- package/dist/sql/generator.d.ts +1 -81
- package/dist/sql/generator.js +0 -29
- package/dist/sql/index.d.ts +1 -2
- package/dist/sql/index.js +0 -1
- package/dist/types/api.d.ts +1 -412
- package/dist/types/api.js +0 -7
- package/dist/utils/colors.d.ts +1 -40
- package/dist/utils/colors.js +0 -10
- package/dist/utils/common.d.ts +1 -50
- package/dist/utils/common.js +19 -23
- package/dist/utils/csv.d.ts +1 -15
- package/dist/utils/csv.js +0 -13
- package/dist/utils/datatype.d.ts +1 -49
- package/dist/utils/datatype.js +0 -41
- package/dist/utils/icons.d.ts +1 -11
- package/dist/utils/icons.js +25 -16
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +0 -1
- package/dist/utils/logger.d.ts +1 -10
- package/dist/utils/logger.js +0 -4
- package/dist/views/layouts/main.hbs +14 -5
- package/dist/views/pages/databases.hbs +0 -18
- package/dist/views/pages/designer.hbs +0 -10
- package/dist/views/pages/erd.hbs +1241 -0
- package/dist/views/pages/error.hbs +0 -2
- package/dist/views/pages/form.hbs +0 -5
- package/dist/views/pages/home.hbs +98 -10
- package/dist/views/pages/info.hbs +107 -0
- package/dist/views/pages/login.hbs +0 -13
- package/dist/views/pages/query.hbs +54 -21
- package/dist/views/pages/schema.hbs +0 -20
- package/dist/views/pages/seed.hbs +435 -202
- package/dist/views/pages/table.hbs +0 -14
- package/dist/views/partials/icon.hbs +0 -1
- package/dist/views/partials/navbar.hbs +0 -6
- package/dist/views/partials/sidebar.hbs +12 -8
- package/docs/API.md +6 -1
- package/docs/EXAMPLES.md +3 -0
- package/package.json +7 -5
- package/dist/app.js.map +0 -1
- package/dist/auth/config.js.map +0 -1
- package/dist/auth/crypto.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/routes.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli/args.js.map +0 -1
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/runner.js.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/data/datasets.js.map +0 -1
- package/dist/data/detector.js.map +0 -1
- package/dist/data/engine.js.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/data/strategies.js.map +0 -1
- package/dist/data/types.js.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/db/export.js.map +0 -1
- package/dist/db/filters.js.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/db/introspection.js.map +0 -1
- package/dist/db/manager.js.map +0 -1
- package/dist/db/migrations.js.map +0 -1
- package/dist/db/postgres.js.map +0 -1
- package/dist/db/types.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/public/css/input.css +0 -302
- package/dist/public/js/icons.js +0 -51
- package/dist/routes/api/helpers.js.map +0 -1
- package/dist/routes/api/import-export.js.map +0 -1
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/query.js.map +0 -1
- package/dist/routes/api/rows.js.map +0 -1
- package/dist/routes/api/seed.js.map +0 -1
- package/dist/routes/api/tables.js.map +0 -1
- package/dist/routes/databases.js.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/pages.js.map +0 -1
- package/dist/serverless.js.map +0 -1
- package/dist/sql/classifier.js.map +0 -1
- package/dist/sql/generator.js.map +0 -1
- package/dist/sql/index.js.map +0 -1
- package/dist/types/api.js.map +0 -1
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/common.js.map +0 -1
- package/dist/utils/csv.js.map +0 -1
- package/dist/utils/datatype.js.map +0 -1
- package/dist/utils/icons.js.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/logger.js.map +0 -1
package/dist/db/database.d.ts
CHANGED
|
@@ -1,119 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type ColumnDef, type IndexDef } from '../sql/generator';
|
|
3
|
-
import type { DatabaseDialect, DbOpenOptions, IDatabase, ReferencingTableInfo, Result, RowFilters, SavedQuery, SchemaInfo, SQLInputValue, TableInfoData, TableListItem, WhereClause } from './types';
|
|
4
|
-
export * from './types';
|
|
5
|
-
export * from './filters';
|
|
6
|
-
/**
|
|
7
|
-
* Promise-style wrapper around the better-sqlite3 driver.
|
|
8
|
-
* Every call returns a consistent `{ success, data?, error? }` shape and
|
|
9
|
-
* performs one-time, idempotent schema initialization.
|
|
10
|
-
*/
|
|
11
|
-
export declare class SqliteDatabase implements IDatabase {
|
|
12
|
-
private db;
|
|
13
|
-
private logger;
|
|
14
|
-
readonly path: string;
|
|
15
|
-
readonly isReadOnly: boolean;
|
|
16
|
-
readonly dialect: DatabaseDialect;
|
|
17
|
-
constructor(dbPath: string, logger: Logger, options?: DbOpenOptions);
|
|
18
|
-
private readonlyBlocked;
|
|
19
|
-
close(): void;
|
|
20
|
-
private initSchema;
|
|
21
|
-
private tryRun;
|
|
22
|
-
/** Run an atomic transaction. Reverts on any error and enforces read-only mode. */
|
|
23
|
-
private transaction;
|
|
24
|
-
private toBind;
|
|
25
|
-
all(sql: string, params?: SQLInputValue[]): Promise<Result<unknown[]>>;
|
|
26
|
-
run(sql: string, params?: SQLInputValue[]): Promise<Result<{
|
|
27
|
-
changes: number;
|
|
28
|
-
lastInsertRowid: number | null;
|
|
29
|
-
}>>;
|
|
30
|
-
execResult(sql: string): Promise<Result<{
|
|
31
|
-
changes?: number;
|
|
32
|
-
}>>;
|
|
33
|
-
hasMultipleStatements(sql: string): boolean;
|
|
34
|
-
runWrite(sql: string): Promise<Result<{
|
|
35
|
-
changes?: number;
|
|
36
|
-
}>>;
|
|
37
|
-
listTables(): Promise<Result<TableListItem[]>>;
|
|
38
|
-
getTableInfo(table: string): Promise<Result<TableInfoData>>;
|
|
39
|
-
getRowCount(table: string, filters?: RowFilters): Promise<Result<number>>;
|
|
40
|
-
getRows(table: string, opts?: {
|
|
41
|
-
page?: number;
|
|
42
|
-
limit?: number;
|
|
43
|
-
orderBy?: string;
|
|
44
|
-
orderDir?: 'asc' | 'desc';
|
|
45
|
-
filters?: RowFilters;
|
|
46
|
-
}): Promise<Result<Record<string, unknown>[]>>;
|
|
47
|
-
getAllRows(table: string): Promise<Result<Record<string, unknown>[]>>;
|
|
48
|
-
getRow(table: string, where: WhereClause[]): Promise<Result<Record<string, unknown> | null>>;
|
|
49
|
-
insertRow(table: string, fields: WhereClause[]): Promise<Result<{
|
|
50
|
-
changes: number;
|
|
51
|
-
lastInsertRowid: number | null;
|
|
52
|
-
}>>;
|
|
53
|
-
/** Insert many rows inside a single atomic transaction. */
|
|
54
|
-
insertRows(table: string, rows: WhereClause[][]): Promise<Result<{
|
|
55
|
-
inserted: number;
|
|
56
|
-
skipped: number;
|
|
57
|
-
}>>;
|
|
58
|
-
updateRow(table: string, fields: WhereClause[], where: WhereClause[]): Promise<Result<{
|
|
59
|
-
changes: number;
|
|
60
|
-
lastInsertRowid: number | null;
|
|
61
|
-
}>>;
|
|
62
|
-
/** Apply many row updates inside a single atomic transaction. */
|
|
63
|
-
updateRows(table: string, rows: {
|
|
64
|
-
fields: WhereClause[];
|
|
65
|
-
where: WhereClause[];
|
|
66
|
-
}[]): Promise<Result<{
|
|
67
|
-
updated: number;
|
|
68
|
-
}>>;
|
|
69
|
-
deleteRow(table: string, where: WhereClause[]): Promise<Result<{
|
|
70
|
-
changes: number;
|
|
71
|
-
lastInsertRowid: number | null;
|
|
72
|
-
}>>;
|
|
73
|
-
/** Delete many rows inside a single atomic transaction. */
|
|
74
|
-
deleteRows(table: string, rows: WhereClause[][]): Promise<Result<{
|
|
75
|
-
deleted: number;
|
|
76
|
-
}>>;
|
|
77
|
-
getRowsByPks(table: string, pks: WhereClause[][]): Promise<Result<Record<string, unknown>[]>>;
|
|
78
|
-
getCreateStatement(table: string): Promise<Result<string | null>>;
|
|
79
|
-
listSavedQueries(): Promise<Result<SavedQuery[]>>;
|
|
80
|
-
saveQuery(name: string, sql: string): Promise<Result<{
|
|
81
|
-
changes: number;
|
|
82
|
-
lastInsertRowid: number | null;
|
|
83
|
-
}>>;
|
|
84
|
-
deleteSavedQuery(id: string | number): Promise<Result<{
|
|
85
|
-
changes: number;
|
|
86
|
-
lastInsertRowid: number | null;
|
|
87
|
-
}>>;
|
|
88
|
-
getSchema(table: string): Promise<Result<SchemaInfo>>;
|
|
89
|
-
getReferencingTables(table: string): Promise<Result<ReferencingTableInfo[]>>;
|
|
90
|
-
getRowsByFk(table: string, column: string, value: unknown, limit?: number): Promise<Result<{
|
|
91
|
-
rows: Record<string, unknown>[];
|
|
92
|
-
total: number;
|
|
93
|
-
}>>;
|
|
94
|
-
renameTable(oldName: string, newName: string): Promise<Result<{
|
|
95
|
-
changes?: number;
|
|
96
|
-
}>>;
|
|
97
|
-
addColumn(table: string, col: ColumnDef): Promise<Result<{
|
|
98
|
-
changes?: number;
|
|
99
|
-
}>>;
|
|
100
|
-
modifyColumn(table: string, oldColName: string, newColDef: ColumnDef): Promise<Result<{
|
|
101
|
-
changes?: number;
|
|
102
|
-
}>>;
|
|
103
|
-
renameColumn(table: string, oldName: string, newName: string): Promise<Result<{
|
|
104
|
-
changes?: number;
|
|
105
|
-
}>>;
|
|
106
|
-
dropColumn(table: string, column: string): Promise<Result<{
|
|
107
|
-
changes?: number;
|
|
108
|
-
}>>;
|
|
109
|
-
dropTable(table: string): Promise<Result<{
|
|
110
|
-
changes?: number;
|
|
111
|
-
}>>;
|
|
112
|
-
createIndex(table: string, index: IndexDef): Promise<Result<{
|
|
113
|
-
changes?: number;
|
|
114
|
-
}>>;
|
|
115
|
-
dropIndex(indexName: string): Promise<Result<{
|
|
116
|
-
changes?: number;
|
|
117
|
-
}>>;
|
|
118
|
-
private getTableInfoSync;
|
|
119
|
-
}
|
|
1
|
+
import type {Logger} from '../utils/logger';import{type ColumnDef,type IndexDef} from '../sql/generator';import type {DatabaseDialect,DbOpenOptions,IDatabase,ReferencingTableInfo,Result,RowFilters,SavedQuery,SchemaInfo,SQLInputValue,TableInfoData,TableListItem,WhereClause} from './types';export * from './types';export * from './filters';export declare class SqliteDatabase implements IDatabase{private db;private logger;readonly path:string;readonly isReadOnly:boolean;readonly dialect:DatabaseDialect;constructor(dbPath:string,logger:Logger,options?:DbOpenOptions);private readonlyBlocked;close():void;private initSchema;private tryRun;private transaction;private toBind;all(sql:string,params?:SQLInputValue[]):Promise<Result<unknown[]>>;run(sql:string,params?:SQLInputValue[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;execResult(sql:string):Promise<Result<{changes?:number;}>>;hasMultipleStatements(sql:string):boolean;runWrite(sql:string):Promise<Result<{changes?:number;}>>;listTables():Promise<Result<TableListItem[]>>;getTableInfo(table:string):Promise<Result<TableInfoData>>;getRowCount(table:string,filters?:RowFilters):Promise<Result<number>>;getRows(table:string,opts?:{page?:number;limit?:number;orderBy?:string;orderDir?:'asc'|'desc';filters?:RowFilters;}):Promise<Result<Record<string,unknown>[]>>;getAllRows(table:string):Promise<Result<Record<string,unknown>[]>>;getRow(table:string,where:WhereClause[]):Promise<Result<Record<string,unknown>|null>>;insertRow(table:string,fields:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;insertRows(table:string,rows:WhereClause[][]):Promise<Result<{inserted:number;skipped:number;}>>;updateRow(table:string,fields:WhereClause[],where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;updateRows(table:string,rows:{fields:WhereClause[];where:WhereClause[];}[]):Promise<Result<{updated:number;}>>;deleteRow(table:string,where:WhereClause[]):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteRows(table:string,rows:WhereClause[][]):Promise<Result<{deleted:number;}>>;getRowsByPks(table:string,pks:WhereClause[][]):Promise<Result<Record<string,unknown>[]>>;getCreateStatement(table:string):Promise<Result<string|null>>;listSavedQueries():Promise<Result<SavedQuery[]>>;saveQuery(name:string,sql:string):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;deleteSavedQuery(id:string|number):Promise<Result<{changes:number;lastInsertRowid:number|null;}>>;getSettings():Promise<Result<Record<string,string>>>;getSchema(table:string):Promise<Result<SchemaInfo>>;getReferencingTables(table:string):Promise<Result<ReferencingTableInfo[]>>;getRowsByFk(table:string,column:string,value:unknown,limit?:number):Promise<Result<{rows:Record<string,unknown>[];total:number;}>>;renameTable(oldName:string,newName:string):Promise<Result<{changes?:number;}>>;addColumn(table:string,col:ColumnDef):Promise<Result<{changes?:number;}>>;modifyColumn(table:string,oldColName:string,newColDef:ColumnDef):Promise<Result<{changes?:number;}>>;renameColumn(table:string,oldName:string,newName:string):Promise<Result<{changes?:number;}>>;dropColumn(table:string,column:string):Promise<Result<{changes?:number;}>>;dropTable(table:string):Promise<Result<{changes?:number;}>>;createIndex(table:string,index:IndexDef):Promise<Result<{changes?:number;}>>;dropIndex(indexName:string):Promise<Result<{changes?:number;}>>;private getTableInfoSync;}
|
package/dist/db/database.js
CHANGED
|
@@ -27,11 +27,6 @@ const introspection_1 = require("./introspection");
|
|
|
27
27
|
const migrations_1 = require("./migrations");
|
|
28
28
|
__exportStar(require("./types"), exports);
|
|
29
29
|
__exportStar(require("./filters"), exports);
|
|
30
|
-
/**
|
|
31
|
-
* Promise-style wrapper around the better-sqlite3 driver.
|
|
32
|
-
* Every call returns a consistent `{ success, data?, error? }` shape and
|
|
33
|
-
* performs one-time, idempotent schema initialization.
|
|
34
|
-
*/
|
|
35
30
|
class SqliteDatabase {
|
|
36
31
|
db;
|
|
37
32
|
logger;
|
|
@@ -85,7 +80,6 @@ class SqliteDatabase {
|
|
|
85
80
|
return { success: false, error: msg };
|
|
86
81
|
}
|
|
87
82
|
}
|
|
88
|
-
/** Run an atomic transaction. Reverts on any error and enforces read-only mode. */
|
|
89
83
|
transaction(fn) {
|
|
90
84
|
if (this.isReadOnly)
|
|
91
85
|
return Promise.resolve(this.readonlyBlocked());
|
|
@@ -100,7 +94,7 @@ class SqliteDatabase {
|
|
|
100
94
|
try {
|
|
101
95
|
this.db.exec('ROLLBACK');
|
|
102
96
|
}
|
|
103
|
-
catch {
|
|
97
|
+
catch { }
|
|
104
98
|
throw err;
|
|
105
99
|
}
|
|
106
100
|
});
|
|
@@ -218,7 +212,6 @@ class SqliteDatabase {
|
|
|
218
212
|
const sql = `INSERT INTO ${(0, generator_1.quoteIdentifier)(table)} (${cols.join(', ')}) VALUES (${fields.map(() => '?').join(', ')})`;
|
|
219
213
|
return this.run(sql, fields.map((f) => this.toBind(f.value)));
|
|
220
214
|
}
|
|
221
|
-
/** Insert many rows inside a single atomic transaction. */
|
|
222
215
|
async insertRows(table, rows) {
|
|
223
216
|
return this.transaction(() => {
|
|
224
217
|
let inserted = 0;
|
|
@@ -239,7 +232,6 @@ class SqliteDatabase {
|
|
|
239
232
|
const sql = `UPDATE ${(0, generator_1.quoteIdentifier)(table)} SET ${sets.join(', ')} WHERE ${conds.join(' AND ')}`;
|
|
240
233
|
return this.run(sql, [...fields.map((f) => this.toBind(f.value)), ...where.map((w) => this.toBind(w.value))]);
|
|
241
234
|
}
|
|
242
|
-
/** Apply many row updates inside a single atomic transaction. */
|
|
243
235
|
async updateRows(table, rows) {
|
|
244
236
|
return this.transaction(() => {
|
|
245
237
|
let updated = 0;
|
|
@@ -260,7 +252,6 @@ class SqliteDatabase {
|
|
|
260
252
|
const sql = `DELETE FROM ${(0, generator_1.quoteIdentifier)(table)} WHERE ${conds.join(' AND ')}`;
|
|
261
253
|
return this.run(sql, where.map((w) => this.toBind(w.value)));
|
|
262
254
|
}
|
|
263
|
-
/** Delete many rows inside a single atomic transaction. */
|
|
264
255
|
async deleteRows(table, rows) {
|
|
265
256
|
return this.transaction(() => {
|
|
266
257
|
let deleted = 0;
|
|
@@ -308,6 +299,23 @@ class SqliteDatabase {
|
|
|
308
299
|
async deleteSavedQuery(id) {
|
|
309
300
|
return this.run(`DELETE FROM ${(0, generator_1.quoteIdentifier)(types_1.INTERNAL_TABLES.savedQueries)} WHERE id = ?`, [Number(id)]);
|
|
310
301
|
}
|
|
302
|
+
async getSettings() {
|
|
303
|
+
return this.tryRun(() => {
|
|
304
|
+
const pragmas = ['journal_mode', 'synchronous', 'foreign_keys', 'page_size', 'encoding', 'auto_vacuum', 'mmap_size', 'temp_store'];
|
|
305
|
+
const settings = {};
|
|
306
|
+
for (const p of pragmas) {
|
|
307
|
+
try {
|
|
308
|
+
const row = this.db.prepare(`PRAGMA ${p}`).get();
|
|
309
|
+
if (row && p in row) {
|
|
310
|
+
settings[p] = String(row[p]);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return settings;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
311
319
|
async getSchema(table) {
|
|
312
320
|
return this.tryRun(() => (0, introspection_1.getSchemaSync)(this.db, table));
|
|
313
321
|
}
|
|
@@ -380,7 +388,6 @@ class SqliteDatabase {
|
|
|
380
388
|
const defaultMatches = newColDef.defaultValue === undefined || String(newColDef.defaultValue ?? '').trim() === String(existing.dflt_value ?? '').trim();
|
|
381
389
|
const fkMatches = newColDef.foreignKey === undefined || ((!newColDef.foreignKey && !existingFk) ||
|
|
382
390
|
(newColDef.foreignKey && existingFk && newColDef.foreignKey.table === existingFk.table && newColDef.foreignKey.column === existingFk.to));
|
|
383
|
-
// Fast path: if ONLY the column name changed, use native RENAME COLUMN.
|
|
384
391
|
if (oldColName !== newName && typeMatches && pkMatches && notNullMatches && uniqueMatches && defaultMatches && fkMatches) {
|
|
385
392
|
this.db.exec((0, generator_1.generateRenameColumn)(table, oldColName, newName));
|
|
386
393
|
const existingIdxNames = new Set(indexRows.map((i) => i.name));
|
|
@@ -393,7 +400,7 @@ class SqliteDatabase {
|
|
|
393
400
|
this.db.exec(`DROP INDEX ${(0, generator_1.quoteIdentifier)(defaultOldIdx)};`);
|
|
394
401
|
this.db.exec(`CREATE ${uniqueKeyword}INDEX IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(newIdxName)} ON ${(0, generator_1.quoteIdentifier)(table)} (${(0, generator_1.quoteIdentifier)(newName)});`);
|
|
395
402
|
}
|
|
396
|
-
catch {
|
|
403
|
+
catch { }
|
|
397
404
|
}
|
|
398
405
|
}
|
|
399
406
|
return { changes: 1 };
|
|
@@ -436,7 +443,7 @@ class SqliteDatabase {
|
|
|
436
443
|
this.db.exec(`DROP INDEX ${(0, generator_1.quoteIdentifier)(defaultOldIdx)};`);
|
|
437
444
|
this.db.exec(`CREATE ${uniqueKeyword}INDEX IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(newIdxName)} ON ${(0, generator_1.quoteIdentifier)(table)} (${(0, generator_1.quoteIdentifier)(newName)});`);
|
|
438
445
|
}
|
|
439
|
-
catch {
|
|
446
|
+
catch { }
|
|
440
447
|
}
|
|
441
448
|
}
|
|
442
449
|
return { changes: 1 };
|
|
@@ -468,4 +475,3 @@ class SqliteDatabase {
|
|
|
468
475
|
}
|
|
469
476
|
}
|
|
470
477
|
exports.SqliteDatabase = SqliteDatabase;
|
|
471
|
-
//# sourceMappingURL=database.js.map
|
package/dist/db/export.d.ts
CHANGED
|
@@ -1,12 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export interface DumpResult {
|
|
3
|
-
success: boolean;
|
|
4
|
-
data?: string;
|
|
5
|
-
error?: string;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Produce a downloadable SQL dump: for every table emit its CREATE statement
|
|
9
|
-
* followed by one INSERT statement per row. BLOB values are exported as
|
|
10
|
-
* X'…' literals so they round-trip as real blobs.
|
|
11
|
-
*/
|
|
12
|
-
export declare function generateSqlDump(db: IDatabase): Promise<DumpResult>;
|
|
1
|
+
import type {IDatabase} from './types';export interface DumpResult{success:boolean;data?:string;error?:string;}export declare function generateSqlDump(db:IDatabase):Promise<DumpResult>;export declare function generateSchemaDump(db:IDatabase):Promise<DumpResult>;
|
package/dist/db/export.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateSqlDump = generateSqlDump;
|
|
4
|
+
exports.generateSchemaDump = generateSchemaDump;
|
|
4
5
|
const generator_1 = require("../sql/generator");
|
|
5
|
-
/**
|
|
6
|
-
* Produce a downloadable SQL dump: for every table emit its CREATE statement
|
|
7
|
-
* followed by one INSERT statement per row. BLOB values are exported as
|
|
8
|
-
* X'…' literals so they round-trip as real blobs.
|
|
9
|
-
*/
|
|
10
6
|
async function generateSqlDump(db) {
|
|
11
7
|
const out = [];
|
|
12
8
|
if (db.dialect === 'sqlite') {
|
|
@@ -39,4 +35,56 @@ async function generateSqlDump(db) {
|
|
|
39
35
|
out.push('COMMIT;');
|
|
40
36
|
return { success: true, data: out.join('\n') };
|
|
41
37
|
}
|
|
42
|
-
|
|
38
|
+
async function generateSchemaDump(db) {
|
|
39
|
+
const out = [];
|
|
40
|
+
if (db.dialect === 'sqlite') {
|
|
41
|
+
const allSchemas = await db.all(`SELECT sql FROM sqlite_master WHERE sql IS NOT NULL AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_saved_queries'`);
|
|
42
|
+
if (allSchemas.success && allSchemas.data) {
|
|
43
|
+
for (const row of allSchemas.data) {
|
|
44
|
+
let stmt = String(row.sql).trim();
|
|
45
|
+
if (!stmt.endsWith(';'))
|
|
46
|
+
stmt += ';';
|
|
47
|
+
out.push(stmt);
|
|
48
|
+
out.push('');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return { success: false, error: allSchemas.error ?? 'Failed to read sqlite_master.' };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const tables = await db.listTables();
|
|
57
|
+
if (!tables.success)
|
|
58
|
+
return { success: false, error: tables.error ?? 'Failed to list tables.' };
|
|
59
|
+
for (const t of tables.data ?? []) {
|
|
60
|
+
const name = t.name;
|
|
61
|
+
const info = await db.getTableInfo(name);
|
|
62
|
+
if (info.success && info.data) {
|
|
63
|
+
if (info.data.sql) {
|
|
64
|
+
out.push(info.data.sql.trim());
|
|
65
|
+
}
|
|
66
|
+
if (info.data.foreignKeys && info.data.foreignKeys.length > 0) {
|
|
67
|
+
for (const fk of info.data.foreignKeys) {
|
|
68
|
+
if (fk.from && fk.to && fk.table) {
|
|
69
|
+
let action = '';
|
|
70
|
+
if (fk.on_delete && fk.on_delete !== 'NO ACTION')
|
|
71
|
+
action += ` ON DELETE ${fk.on_delete}`;
|
|
72
|
+
if (fk.on_update && fk.on_update !== 'NO ACTION')
|
|
73
|
+
action += ` ON UPDATE ${fk.on_update}`;
|
|
74
|
+
out.push(`ALTER TABLE "${name}" ADD FOREIGN KEY ("${fk.from}") REFERENCES "${fk.table}" ("${fk.to}")${action};`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (info.data.indexes && info.data.indexes.length > 0) {
|
|
79
|
+
for (const idx of info.data.indexes) {
|
|
80
|
+
if (idx.sql) {
|
|
81
|
+
out.push(idx.sql.trim() + ';');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
out.push('');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { success: true, data: out.join('\n').trim() };
|
|
90
|
+
}
|
package/dist/db/filters.d.ts
CHANGED
|
@@ -1,22 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/** Escape LIKE wildcards so user filter text is matched literally. */
|
|
3
|
-
export declare function escapeLike(s: string): string;
|
|
4
|
-
/**
|
|
5
|
-
* Build a parameterized WHERE clause from per-column filters.
|
|
6
|
-
*
|
|
7
|
-
* A filter value is either:
|
|
8
|
-
* - the legacy string syntax: `=value` exact, `!=value`, `>value`, `>=value`,
|
|
9
|
-
* `<value`, `<=value`, `value*` prefix, anything else → substring match; or
|
|
10
|
-
* - a structured `FilterCondition` (or array of them) produced by the
|
|
11
|
-
* type-aware filter form (FK dropdowns, boolean toggles, date/number ranges).
|
|
12
|
-
*/
|
|
13
|
-
export declare function pushFilterCondition(conds: string[], params: SQLInputValue[], quotedCol: string, c: FilterCondition): void;
|
|
14
|
-
export declare function buildFilterClause(filters: RowFilters | undefined, availableCols: string[]): {
|
|
15
|
-
where: string;
|
|
16
|
-
params: SQLInputValue[];
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Replace SQLite-style `?` placeholders with PostgreSQL-style `$1, $2, ...`
|
|
20
|
-
* placeholders while safely preserving single-quoted string literals.
|
|
21
|
-
*/
|
|
22
|
-
export declare function convertPlaceholdersToPostgres(sql: string, startIdx?: number): string;
|
|
1
|
+
import type {FilterCondition,RowFilters,SQLInputValue} from './types';export declare function escapeLike(s:string):string;export declare function pushFilterCondition(conds:string[],params:SQLInputValue[],quotedCol:string,c:FilterCondition):void;export declare function buildFilterClause(filters:RowFilters|undefined,availableCols:string[]):{where:string;params:SQLInputValue[];};export declare function convertPlaceholdersToPostgres(sql:string,startIdx?:number):string;
|
package/dist/db/filters.js
CHANGED
|
@@ -5,19 +5,9 @@ exports.pushFilterCondition = pushFilterCondition;
|
|
|
5
5
|
exports.buildFilterClause = buildFilterClause;
|
|
6
6
|
exports.convertPlaceholdersToPostgres = convertPlaceholdersToPostgres;
|
|
7
7
|
const generator_1 = require("../sql/generator");
|
|
8
|
-
/** Escape LIKE wildcards so user filter text is matched literally. */
|
|
9
8
|
function escapeLike(s) {
|
|
10
9
|
return String(s).replace(/[\\%_]/g, (m) => '\\' + m);
|
|
11
10
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Build a parameterized WHERE clause from per-column filters.
|
|
14
|
-
*
|
|
15
|
-
* A filter value is either:
|
|
16
|
-
* - the legacy string syntax: `=value` exact, `!=value`, `>value`, `>=value`,
|
|
17
|
-
* `<value`, `<=value`, `value*` prefix, anything else → substring match; or
|
|
18
|
-
* - a structured `FilterCondition` (or array of them) produced by the
|
|
19
|
-
* type-aware filter form (FK dropdowns, boolean toggles, date/number ranges).
|
|
20
|
-
*/
|
|
21
11
|
function pushFilterCondition(conds, params, quotedCol, c) {
|
|
22
12
|
const value = String(c.value ?? '');
|
|
23
13
|
switch (c.op) {
|
|
@@ -88,7 +78,6 @@ function buildFilterClause(filters, availableCols) {
|
|
|
88
78
|
pushFilterCondition(conds, params, q, raw);
|
|
89
79
|
continue;
|
|
90
80
|
}
|
|
91
|
-
// Legacy string syntax.
|
|
92
81
|
const value = String(raw ?? '').trim();
|
|
93
82
|
if (value === '')
|
|
94
83
|
continue;
|
|
@@ -127,10 +116,6 @@ function buildFilterClause(filters, availableCols) {
|
|
|
127
116
|
}
|
|
128
117
|
return { where: conds.length ? ` WHERE ${conds.join(' AND ')}` : '', params };
|
|
129
118
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Replace SQLite-style `?` placeholders with PostgreSQL-style `$1, $2, ...`
|
|
132
|
-
* placeholders while safely preserving single-quoted string literals.
|
|
133
|
-
*/
|
|
134
119
|
function convertPlaceholdersToPostgres(sql, startIdx = 1) {
|
|
135
120
|
let idx = startIdx;
|
|
136
121
|
let inString = false;
|
|
@@ -155,4 +140,3 @@ function convertPlaceholdersToPostgres(sql, startIdx = 1) {
|
|
|
155
140
|
}
|
|
156
141
|
return result;
|
|
157
142
|
}
|
|
158
|
-
//# sourceMappingURL=filters.js.map
|
package/dist/db/index.d.ts
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './filters';
|
|
3
|
-
export * from './introspection';
|
|
4
|
-
export * from './migrations';
|
|
5
|
-
export * from './database';
|
|
6
|
-
export * from './postgres';
|
|
7
|
-
export * from './manager';
|
|
8
|
-
export * from './export';
|
|
1
|
+
export * from './types';export * from './filters';export * from './introspection';export * from './migrations';export * from './database';export * from './postgres';export * from './manager';export * from './export';
|
package/dist/db/index.js
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
import type Database from 'better-sqlite3';
|
|
2
|
-
import type { ReferencingTableInfo, SchemaInfo, TableInfoData, TableListItem } from './types';
|
|
3
|
-
export declare function listTablesSync(db: Database.Database): TableListItem[];
|
|
4
|
-
export declare function getTableInfoSync(db: Database.Database, table: string): TableInfoData;
|
|
5
|
-
export declare function getSchemaSync(db: Database.Database, table: string): SchemaInfo;
|
|
6
|
-
export declare function getReferencingTablesSync(db: Database.Database, table: string): ReferencingTableInfo[];
|
|
1
|
+
import type Database from 'better-sqlite3';import type {ReferencingTableInfo,SchemaInfo,TableInfoData,TableListItem} from './types';export declare function listTablesSync(db:Database.Database):TableListItem[];export declare function getTableInfoSync(db:Database.Database,table:string):TableInfoData;export declare function getSchemaSync(db:Database.Database,table:string):SchemaInfo;export declare function getReferencingTablesSync(db:Database.Database,table:string):ReferencingTableInfo[];
|
package/dist/db/introspection.js
CHANGED
|
@@ -11,13 +11,11 @@ function listTablesSync(db) {
|
|
|
11
11
|
.all();
|
|
12
12
|
return rows.map((r) => ({ name: r.name }));
|
|
13
13
|
}
|
|
14
|
-
/** Get all tables non-internal in the SQLite database. */
|
|
15
14
|
function getTableNames(db) {
|
|
16
15
|
return db
|
|
17
16
|
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'")
|
|
18
17
|
.all().map((r) => r.name);
|
|
19
18
|
}
|
|
20
|
-
/** Discover all foreign keys declared across all other tables pointing to `targetTable`. */
|
|
21
19
|
function getIncomingFks(db, targetTable) {
|
|
22
20
|
const refs = [];
|
|
23
21
|
for (const t of getTableNames(db)) {
|
|
@@ -31,7 +29,6 @@ function getIncomingFks(db, targetTable) {
|
|
|
31
29
|
}
|
|
32
30
|
}
|
|
33
31
|
catch {
|
|
34
|
-
/* ignore unreadable tables */
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
34
|
return refs;
|
|
@@ -162,11 +159,9 @@ function getReferencingTablesSync(db, table) {
|
|
|
162
159
|
refCount = Number(row.c);
|
|
163
160
|
}
|
|
164
161
|
catch {
|
|
165
|
-
/* count is best-effort */
|
|
166
162
|
}
|
|
167
163
|
result.push({ table: t, refs: tRefs, refCount });
|
|
168
164
|
}
|
|
169
165
|
result.sort((a, b) => a.table.localeCompare(b.table));
|
|
170
166
|
return result;
|
|
171
167
|
}
|
|
172
|
-
//# sourceMappingURL=introspection.js.map
|
package/dist/db/manager.d.ts
CHANGED
|
@@ -1,81 +1 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type Logger } from '../utils/logger';
|
|
3
|
-
export interface DbManagerOptions {
|
|
4
|
-
/** Directory of database files. Scanned for known extensions; new DBs are created here. */
|
|
5
|
-
dir?: string;
|
|
6
|
-
/** Explicit database file paths or connection strings. */
|
|
7
|
-
files?: string[];
|
|
8
|
-
/** Named database connections map (e.g. { "mydb": "postgresql://...", "name1": "postgresql://..." }). */
|
|
9
|
-
connections?: Record<string, string>;
|
|
10
|
-
/** Open every managed database read-only (no writes, no create/delete of files). */
|
|
11
|
-
readonly?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface DatabaseEntry {
|
|
14
|
-
/** Stable, URL-safe id (usually the file name or connection name, deduped on collision). */
|
|
15
|
-
id: string;
|
|
16
|
-
/** Name for display. */
|
|
17
|
-
name: string;
|
|
18
|
-
/** Path on disk or sanitized connection URI. */
|
|
19
|
-
path: string;
|
|
20
|
-
/** Database dialect (sqlite or postgres). */
|
|
21
|
-
dialect: 'sqlite' | 'postgres';
|
|
22
|
-
size: number;
|
|
23
|
-
modified: string;
|
|
24
|
-
/** Whether this specific database is opened in read-only mode. */
|
|
25
|
-
readonly: boolean;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Manages multiple SQLite database files and PostgreSQL database connections.
|
|
29
|
-
*
|
|
30
|
-
* Databases come from three sources:
|
|
31
|
-
* - a `connections` map — named PostgreSQL or SQLite connection strings (e.g. from JSON config),
|
|
32
|
-
* - a `dir` — every SQLite file with a known extension is scanned in,
|
|
33
|
-
* - an explicit `files[]` array — specific file locations or connection strings.
|
|
34
|
-
*/
|
|
35
|
-
export declare class DbManager {
|
|
36
|
-
private logger;
|
|
37
|
-
private dir?;
|
|
38
|
-
private createDir;
|
|
39
|
-
private readonly readonlyMode;
|
|
40
|
-
private files;
|
|
41
|
-
private idByPath;
|
|
42
|
-
private pathById;
|
|
43
|
-
private nameById;
|
|
44
|
-
private readonlyById;
|
|
45
|
-
private openDbs;
|
|
46
|
-
constructor(options: DbManagerOptions | string, logger?: Logger);
|
|
47
|
-
get directory(): string;
|
|
48
|
-
/** True when this manager opens every database read-only. */
|
|
49
|
-
get isReadOnly(): boolean;
|
|
50
|
-
isDbFile(name: string): boolean;
|
|
51
|
-
private registerConnections;
|
|
52
|
-
private registerDirFiles;
|
|
53
|
-
private registerExplicitFiles;
|
|
54
|
-
private addNamedTarget;
|
|
55
|
-
private addFile;
|
|
56
|
-
/** List all managed databases (metadata only — does not open them). */
|
|
57
|
-
list(): DatabaseEntry[];
|
|
58
|
-
has(id: string): boolean;
|
|
59
|
-
/** True if global manager is in readonly mode or this database is explicitly marked read-only. */
|
|
60
|
-
isDbReadOnly(id: string): boolean;
|
|
61
|
-
/** Set or toggle read-only mode for a specific database id. */
|
|
62
|
-
setReadonly(id: string, readonly: boolean): void;
|
|
63
|
-
/** Open (and cache) a database by id; creates the file if it is new SQLite database. */
|
|
64
|
-
open(id: string, readonlyOverride?: boolean): IDatabase;
|
|
65
|
-
/**
|
|
66
|
-
* Register and open an existing database file by path, returning its id.
|
|
67
|
-
* Used by the "Open an existing database" file browser. Validates that the
|
|
68
|
-
* file is a readable SQLite database before keeping it registered.
|
|
69
|
-
*/
|
|
70
|
-
openFile(absPath: string, readonly?: boolean): string;
|
|
71
|
-
get(id: string): IDatabase | undefined;
|
|
72
|
-
/** Count the tables in a database (opens it if necessary). */
|
|
73
|
-
countTables(id: string): Promise<number>;
|
|
74
|
-
/** Create a new (empty) SQLite database. Returns its id. */
|
|
75
|
-
create(name: string): string;
|
|
76
|
-
/** Dynamically register a named PostgreSQL or SQLite connection string. Returns its id. */
|
|
77
|
-
addConnection(name: string, connectionString: string, readonly?: boolean): string;
|
|
78
|
-
/** Close and delete a database file (including WAL/SHM sidecars). */
|
|
79
|
-
remove(id: string): void;
|
|
80
|
-
closeAll(): void;
|
|
81
|
-
}
|
|
1
|
+
import type {IDatabase} from './types';import{type Logger} from '../utils/logger';export interface DbManagerOptions{dir?:string;files?:string[];connections?:Record<string,string>;readonly ?:boolean;}export interface DatabaseEntry{id:string;name:string;path:string;dialect:'sqlite'|'postgres';size:number;modified:string;readonly :boolean;}export declare class DbManager{private logger;private dir?;private createDir;private readonly readonlyMode;private files;private idByPath;private pathById;private nameById;private readonlyById;private openDbs;constructor(options:DbManagerOptions|string,logger?:Logger);get directory():string;get isReadOnly():boolean;isDbFile(name:string):boolean;private registerConnections;private registerDirFiles;private registerExplicitFiles;private addNamedTarget;private addFile;list():DatabaseEntry[];has(id:string):boolean;isDbReadOnly(id:string):boolean;setReadonly(id:string,readonly :boolean):void;open(id:string,readonlyOverride?:boolean):IDatabase;openFile(absPath:string,readonly ?:boolean):string;get(id:string):IDatabase|undefined;countTables(id:string):Promise<number>;create(name:string):string;addConnection(name:string,connectionString:string,readonly ?:boolean):string;remove(id:string):void;closeAll():void;}
|