admindb 2.2.1 → 2.3.0

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.
Files changed (87) hide show
  1. package/README.md +368 -364
  2. package/dist/app.js +6 -9
  3. package/dist/auth/config.d.ts +1 -1
  4. package/dist/auth/config.js +18 -30
  5. package/dist/auth/crypto.js +11 -21
  6. package/dist/auth/middleware.js +9 -16
  7. package/dist/auth/routes.js +9 -15
  8. package/dist/cli/args.d.ts +1 -1
  9. package/dist/cli/args.js +15 -26
  10. package/dist/cli/config.js +6 -16
  11. package/dist/cli/runner.js +4 -7
  12. package/dist/data/chain.d.ts +1 -1
  13. package/dist/data/chain.js +40 -617
  14. package/dist/data/datasets.d.ts +1 -1
  15. package/dist/data/datasets.js +43 -1
  16. package/dist/data/detector.js +45 -21
  17. package/dist/data/engine.d.ts +1 -1
  18. package/dist/data/engine.js +483 -142
  19. package/dist/data/index.d.ts +1 -1
  20. package/dist/data/index.js +8 -0
  21. package/dist/data/prng.d.ts +1 -0
  22. package/dist/data/prng.js +73 -0
  23. package/dist/data/registry.d.ts +1 -0
  24. package/dist/data/registry.js +805 -0
  25. package/dist/data/schema-graph.d.ts +1 -0
  26. package/dist/data/schema-graph.js +210 -0
  27. package/dist/data/strategies.d.ts +1 -1
  28. package/dist/data/strategies.js +44 -283
  29. package/dist/data/templates.d.ts +1 -0
  30. package/dist/data/templates.js +134 -0
  31. package/dist/data/types.d.ts +1 -1
  32. package/dist/data/validator.d.ts +1 -0
  33. package/dist/data/validator.js +160 -0
  34. package/dist/db/database.js +9 -14
  35. package/dist/db/export.js +32 -55
  36. package/dist/db/filters.d.ts +1 -1
  37. package/dist/db/filters.js +15 -38
  38. package/dist/db/introspection.js +4 -7
  39. package/dist/db/manager.js +27 -51
  40. package/dist/db/migrations.js +7 -14
  41. package/dist/db/postgres.js +30 -78
  42. package/dist/index.d.ts +1 -1
  43. package/dist/public/css/app.css +1 -1
  44. package/dist/public/js/browse.js +1 -1
  45. package/dist/public/js/inspector.js +1 -1
  46. package/dist/public/js/query.js +1 -1
  47. package/dist/public/js/seed.js +1 -1
  48. package/dist/routes/api/erd.js +3 -8
  49. package/dist/routes/api/helpers.d.ts +1 -1
  50. package/dist/routes/api/helpers.js +75 -25
  51. package/dist/routes/api/import-export.js +1 -2
  52. package/dist/routes/api/query.js +2 -6
  53. package/dist/routes/api/rows.js +4 -8
  54. package/dist/routes/api/seed.js +35 -21
  55. package/dist/routes/api/tables.js +15 -30
  56. package/dist/routes/databases.js +8 -26
  57. package/dist/routes/pages.js +67 -18
  58. package/dist/serverless.js +15 -40
  59. package/dist/sql/generator.d.ts +1 -1
  60. package/dist/sql/generator.js +35 -109
  61. package/dist/types/api.d.ts +1 -1
  62. package/dist/utils/common.d.ts +1 -1
  63. package/dist/utils/common.js +45 -85
  64. package/dist/utils/csv.d.ts +1 -1
  65. package/dist/utils/csv.js +11 -17
  66. package/dist/utils/datatype.js +46 -60
  67. package/dist/utils/icons.js +8 -8
  68. package/dist/views/layouts/main.hbs +1 -87
  69. package/dist/views/pages/databases.hbs +1 -233
  70. package/dist/views/pages/designer.hbs +1 -89
  71. package/dist/views/pages/erd.hbs +1 -1241
  72. package/dist/views/pages/error.hbs +1 -10
  73. package/dist/views/pages/form.hbs +1 -59
  74. package/dist/views/pages/home.hbs +1 -220
  75. package/dist/views/pages/info.hbs +1 -107
  76. package/dist/views/pages/login.hbs +1 -98
  77. package/dist/views/pages/query.hbs +1 -129
  78. package/dist/views/pages/schema.hbs +1 -298
  79. package/dist/views/pages/seed-select.hbs +251 -0
  80. package/dist/views/pages/seed.hbs +256 -414
  81. package/dist/views/pages/table.hbs +1 -327
  82. package/dist/views/partials/navbar.hbs +1 -83
  83. package/dist/views/partials/sidebar.hbs +1 -129
  84. package/docs/API.md +149 -149
  85. package/docs/EXAMPLES.md +579 -579
  86. package/docs/SECURITY.md +265 -265
  87. package/package.json +79 -79
@@ -27,12 +27,11 @@ class DbManager {
27
27
  this.logger = logger ?? (0, logger_1.createLogger)('info', 'admindb');
28
28
  this.dir = opts.dir ? node_path_1.default.resolve(opts.dir) : undefined;
29
29
  this.createDir = this.dir ?? process.cwd();
30
- this.readonlyMode = !!opts.readonly;
30
+ this.readonlyMode = Boolean(opts.readonly);
31
31
  if (this.dir)
32
32
  (0, node_fs_1.mkdirSync)(this.dir, { recursive: true });
33
- if (opts.connections) {
33
+ if (opts.connections)
34
34
  this.registerConnections(opts.connections);
35
- }
36
35
  this.registerDirFiles();
37
36
  this.registerExplicitFiles(opts.files ?? []);
38
37
  }
@@ -48,28 +47,24 @@ class DbManager {
48
47
  }
49
48
  registerConnections(conns) {
50
49
  for (const [name, target] of Object.entries(conns ?? {})) {
51
- if (!name || !target)
52
- continue;
53
- const cleanTarget = String(target).trim();
54
- if (!cleanTarget)
55
- continue;
56
- this.addNamedTarget(name.trim(), cleanTarget);
50
+ const cleanTarget = String(target ?? '').trim();
51
+ if (name && cleanTarget)
52
+ this.addNamedTarget(name.trim(), cleanTarget);
57
53
  }
58
54
  }
59
55
  registerDirFiles() {
60
56
  if (!this.dir)
61
57
  return;
62
- let names = [];
63
58
  try {
64
- names = (0, node_fs_1.readdirSync)(this.dir)
59
+ const names = (0, node_fs_1.readdirSync)(this.dir)
65
60
  .filter((n) => this.isDbFile(n))
66
61
  .sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }));
62
+ for (const name of names)
63
+ this.addFile(node_path_1.default.join(this.dir, name));
67
64
  }
68
65
  catch (err) {
69
66
  this.logger.warn(`Failed to list database directory ${this.dir}: ${(0, common_1.errorMessage)(err)}`);
70
67
  }
71
- for (const name of names)
72
- this.addFile(node_path_1.default.join(this.dir, name));
73
68
  }
74
69
  registerExplicitFiles(files) {
75
70
  for (const f of files ?? []) {
@@ -79,12 +74,9 @@ class DbManager {
79
74
  if ((0, common_1.isPostgresConnectionString)(raw)) {
80
75
  let name = 'postgres';
81
76
  try {
82
- const u = new URL(raw);
83
- name = u.pathname.replace(/^\//, '') || 'postgres';
84
- }
85
- catch {
86
- name = 'postgres';
77
+ name = new URL(raw).pathname.replace(/^\//, '') || 'postgres';
87
78
  }
79
+ catch { }
88
80
  this.addNamedTarget(name, raw);
89
81
  continue;
90
82
  }
@@ -99,10 +91,8 @@ class DbManager {
99
91
  addNamedTarget(name, target) {
100
92
  let id = name;
101
93
  let n = 2;
102
- while (this.pathById.has(id)) {
103
- id = `${name}__${n}`;
104
- n += 1;
105
- }
94
+ while (this.pathById.has(id))
95
+ id = `${name}__${n++}`;
106
96
  this.files.push(target);
107
97
  this.idByPath.set(target, id);
108
98
  this.pathById.set(id, target);
@@ -116,9 +106,7 @@ class DbManager {
116
106
  let n = 2;
117
107
  while (this.pathById.has(id)) {
118
108
  const ext = node_path_1.default.extname(base);
119
- const stem = node_path_1.default.basename(base, ext);
120
- id = `${stem}__${n}${ext}`;
121
- n += 1;
109
+ id = `${node_path_1.default.basename(base, ext)}__${n++}${ext}`;
122
110
  }
123
111
  this.files.push(abs);
124
112
  this.idByPath.set(abs, id);
@@ -151,8 +139,7 @@ class DbManager {
151
139
  size = st.size;
152
140
  modified = st.mtime.toISOString();
153
141
  }
154
- catch {
155
- }
142
+ catch { }
156
143
  entries.push({
157
144
  id,
158
145
  name: this.nameById.get(id) ?? node_path_1.default.basename(target),
@@ -176,8 +163,7 @@ class DbManager {
176
163
  if (this.readonlyMode && !readonly) {
177
164
  throw new Error('Manager is in global read-only mode — databases cannot be made writable.');
178
165
  }
179
- const current = this.readonlyById.get(id);
180
- if (current === readonly)
166
+ if (this.readonlyById.get(id) === readonly)
181
167
  return;
182
168
  this.readonlyById.set(id, readonly);
183
169
  const db = this.openDbs.get(id);
@@ -185,8 +171,7 @@ class DbManager {
185
171
  try {
186
172
  db.close();
187
173
  }
188
- catch {
189
- }
174
+ catch { }
190
175
  this.openDbs.delete(id);
191
176
  }
192
177
  }
@@ -200,18 +185,15 @@ class DbManager {
200
185
  try {
201
186
  db.close();
202
187
  }
203
- catch {
204
- }
188
+ catch { }
205
189
  this.openDbs.delete(id);
206
190
  db = undefined;
207
191
  }
208
192
  if (!db) {
209
- if ((0, common_1.isPostgresConnectionString)(target)) {
210
- db = new postgres_1.PostgresDatabase(target, this.logger.child(`db:${id}`), { readonly: isRo });
211
- }
212
- else {
213
- db = new database_1.SqliteDatabase(target, this.logger.child(`db:${id}`), { readonly: isRo });
214
- }
193
+ const childLogger = this.logger.child(`db:${id}`);
194
+ db = (0, common_1.isPostgresConnectionString)(target)
195
+ ? new postgres_1.PostgresDatabase(target, childLogger, { readonly: isRo })
196
+ : new database_1.SqliteDatabase(target, childLogger, { readonly: isRo });
215
197
  this.openDbs.set(id, db);
216
198
  }
217
199
  return db;
@@ -220,9 +202,8 @@ class DbManager {
220
202
  const abs = node_path_1.default.resolve(String(absPath ?? '').trim());
221
203
  if (!abs)
222
204
  throw new Error('Database path is required.');
223
- if (!(0, node_fs_1.existsSync)(abs) || !(0, node_fs_1.statSync)(abs).isFile()) {
205
+ if (!(0, node_fs_1.existsSync)(abs) || !(0, node_fs_1.statSync)(abs).isFile())
224
206
  throw new Error(`Not a file: ${abs}`);
225
- }
226
207
  const existing = this.idByPath.get(abs);
227
208
  if (existing) {
228
209
  if (readonly !== undefined)
@@ -253,8 +234,7 @@ class DbManager {
253
234
  }
254
235
  async countTables(id) {
255
236
  try {
256
- const db = this.open(id);
257
- const r = await db.listTables();
237
+ const r = await this.open(id).listTables();
258
238
  return r.success ? (r.data?.length ?? 0) : 0;
259
239
  }
260
240
  catch {
@@ -284,8 +264,7 @@ class DbManager {
284
264
  let cleanName = String(name ?? '').trim();
285
265
  if (!cleanName) {
286
266
  try {
287
- const u = new URL(raw);
288
- cleanName = u.pathname.replace(/^\//, '') || 'postgres';
267
+ cleanName = new URL(raw).pathname.replace(/^\//, '') || 'postgres';
289
268
  }
290
269
  catch {
291
270
  cleanName = 'postgres';
@@ -310,8 +289,7 @@ class DbManager {
310
289
  try {
311
290
  db.close();
312
291
  }
313
- catch {
314
- }
292
+ catch { }
315
293
  this.openDbs.delete(id);
316
294
  }
317
295
  this.pathById.delete(id);
@@ -324,8 +302,7 @@ class DbManager {
324
302
  try {
325
303
  (0, node_fs_1.unlinkSync)(target + suffix);
326
304
  }
327
- catch {
328
- }
305
+ catch { }
329
306
  }
330
307
  }
331
308
  }
@@ -334,8 +311,7 @@ class DbManager {
334
311
  try {
335
312
  db.close();
336
313
  }
337
- catch {
338
- }
314
+ catch { }
339
315
  }
340
316
  this.openDbs.clear();
341
317
  }
@@ -12,9 +12,8 @@ function modifyTableStructureSync(db, table, transformColumns, renamedOldCol, re
12
12
  for (const ix of indexRows) {
13
13
  if (ix.unique) {
14
14
  const ixCols = db.prepare(`PRAGMA index_info(${(0, generator_1.quoteIdentifier)(ix.name)})`).all().map((c) => c.name);
15
- if (ixCols.length === 1) {
15
+ if (ixCols.length === 1)
16
16
  uniqueCols.add(ixCols[0]);
17
- }
18
17
  }
19
18
  }
20
19
  const userIndexes = [];
@@ -32,7 +31,7 @@ function modifyTableStructureSync(db, table, transformColumns, renamedOldCol, re
32
31
  }
33
32
  userIndexes.push({
34
33
  name: ixName,
35
- unique: !!ix.unique,
34
+ unique: Boolean(ix.unique),
36
35
  columns: ixCols.map((c) => (renamedOldCol && renamedNewCol && c === renamedOldCol ? renamedNewCol : c)),
37
36
  });
38
37
  }
@@ -43,7 +42,7 @@ function modifyTableStructureSync(db, table, transformColumns, renamedOldCol, re
43
42
  name: c.name,
44
43
  type: c.type,
45
44
  primaryKey: c.pk > 0,
46
- notNull: !!c.notnull,
45
+ notNull: Boolean(c.notnull),
47
46
  unique: uniqueCols.has(c.name),
48
47
  defaultValue: c.dflt_value,
49
48
  foreignKey: existingFk ? { table: existingFk.table, column: existingFk.to ?? '' } : null,
@@ -56,17 +55,13 @@ function modifyTableStructureSync(db, table, transformColumns, renamedOldCol, re
56
55
  const matchingOldCols = [];
57
56
  const matchingNewCols = [];
58
57
  for (const nc of newCols) {
59
- let sourceColName = nc.name;
60
- if (renamedOldCol && renamedNewCol && nc.name === renamedNewCol) {
61
- sourceColName = renamedOldCol;
62
- }
58
+ const sourceColName = renamedOldCol && renamedNewCol && nc.name === renamedNewCol ? renamedOldCol : nc.name;
63
59
  if (oldColMap.has(sourceColName)) {
64
60
  matchingOldCols.push((0, generator_1.quoteIdentifier)(sourceColName));
65
61
  matchingNewCols.push((0, generator_1.quoteIdentifier)(nc.name));
66
62
  }
67
63
  }
68
- db.exec('PRAGMA foreign_keys = OFF;');
69
- db.exec('BEGIN TRANSACTION;');
64
+ db.exec('PRAGMA foreign_keys = OFF;\nBEGIN TRANSACTION;');
70
65
  try {
71
66
  db.exec(createSql);
72
67
  if (matchingOldCols.length > 0) {
@@ -80,11 +75,9 @@ function modifyTableStructureSync(db, table, transformColumns, renamedOldCol, re
80
75
  try {
81
76
  db.exec(`CREATE ${uq}INDEX IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(ix.name)} ON ${(0, generator_1.quoteIdentifier)(table)} (${ixColsStr});`);
82
77
  }
83
- catch {
84
- }
78
+ catch { }
85
79
  }
86
- const fkCheck = db.prepare('PRAGMA foreign_key_check;').all();
87
- if (fkCheck.length > 0) {
80
+ if (db.prepare('PRAGMA foreign_key_check;').all().length > 0) {
88
81
  throw new Error('Foreign key constraint check failed after schema modification.');
89
82
  }
90
83
  db.exec('COMMIT;');
@@ -30,21 +30,17 @@ class PostgresDatabase {
30
30
  if (sslMode === 'disable') {
31
31
  sslConfig = false;
32
32
  }
33
- else if (sslConfig === undefined) {
34
- if (sslMode === 'require' || sslMode === 'prefer' || sslMode === 'no-verify' || !isLocal) {
35
- sslConfig = { rejectUnauthorized: false };
36
- }
33
+ else if (sslConfig === undefined && (sslMode === 'require' || sslMode === 'prefer' || sslMode === 'no-verify' || !isLocal)) {
34
+ sslConfig = { rejectUnauthorized: false };
37
35
  }
38
36
  }
39
- catch {
40
- }
37
+ catch { }
41
38
  }
42
39
  else if (opts.host && sslConfig === undefined) {
43
40
  const host = opts.host.toLowerCase();
44
41
  const isLocal = host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '0.0.0.0';
45
- if (!isLocal) {
42
+ if (!isLocal)
46
43
  sslConfig = { rejectUnauthorized: false };
47
- }
48
44
  }
49
45
  const poolConfig = {
50
46
  connectionString: opts.connectionString,
@@ -86,8 +82,7 @@ class PostgresDatabase {
86
82
  }
87
83
  async tryRun(fn) {
88
84
  try {
89
- const data = await fn();
90
- return { success: true, data };
85
+ return { success: true, data: await fn() };
91
86
  }
92
87
  catch (err) {
93
88
  const msg = (0, common_1.errorMessage)(err);
@@ -109,8 +104,7 @@ class PostgresDatabase {
109
104
  try {
110
105
  await client.query('ROLLBACK');
111
106
  }
112
- catch {
113
- }
107
+ catch { }
114
108
  const msg = (0, common_1.errorMessage)(err);
115
109
  this.logger.error(msg);
116
110
  return { success: false, error: msg };
@@ -120,15 +114,14 @@ class PostgresDatabase {
120
114
  }
121
115
  }
122
116
  async initSchema() {
123
- const sql = `
117
+ await this.pool.query(`
124
118
  CREATE TABLE IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(types_1.INTERNAL_TABLES.savedQueries)} (
125
119
  id SERIAL PRIMARY KEY,
126
120
  name VARCHAR(255) NOT NULL UNIQUE,
127
121
  sql TEXT NOT NULL,
128
122
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
129
123
  );
130
- `;
131
- await this.pool.query(sql);
124
+ `);
132
125
  }
133
126
  hasMultipleStatements(sql) {
134
127
  const s = String(sql ?? '').trim();
@@ -145,18 +138,15 @@ class PostgresDatabase {
145
138
  }
146
139
  inString = !inString;
147
140
  }
148
- else if (ch === ';' && !inString) {
149
- const rest = s.slice(i + 1).trim();
150
- if (rest.length > 0)
151
- count++;
141
+ else if (ch === ';' && !inString && s.slice(i + 1).trim().length > 0) {
142
+ count++;
152
143
  }
153
144
  }
154
145
  return count > 0;
155
146
  }
156
147
  async all(sql, params = []) {
157
148
  return this.tryRun(async () => {
158
- const pgSql = (0, filters_1.convertPlaceholdersToPostgres)(sql);
159
- const res = await this.pool.query(pgSql, params);
149
+ const res = await this.pool.query((0, filters_1.convertPlaceholdersToPostgres)(sql), params);
160
150
  return res.rows;
161
151
  });
162
152
  }
@@ -164,12 +154,8 @@ class PostgresDatabase {
164
154
  if (this.isReadOnly)
165
155
  return this.readonlyBlocked();
166
156
  return this.tryRun(async () => {
167
- const pgSql = (0, filters_1.convertPlaceholdersToPostgres)(sql);
168
- const res = await this.pool.query(pgSql, params);
169
- return {
170
- changes: res.rowCount ?? 0,
171
- lastInsertRowid: null,
172
- };
157
+ const res = await this.pool.query((0, filters_1.convertPlaceholdersToPostgres)(sql), params);
158
+ return { changes: res.rowCount ?? 0, lastInsertRowid: null };
173
159
  });
174
160
  }
175
161
  async execResult(sql) {
@@ -184,15 +170,7 @@ class PostgresDatabase {
184
170
  });
185
171
  }
186
172
  async runWrite(sql) {
187
- if (this.isReadOnly)
188
- return this.readonlyBlocked();
189
- return this.tryRun(async () => {
190
- const res = await this.pool.query(sql);
191
- const changes = Array.isArray(res)
192
- ? res.reduce((acc, r) => acc + (r.rowCount ?? 0), 0)
193
- : res.rowCount ?? undefined;
194
- return { changes };
195
- });
173
+ return this.execResult(sql);
196
174
  }
197
175
  async listTables() {
198
176
  return this.tryRun(async () => {
@@ -293,7 +271,6 @@ class PostgresDatabase {
293
271
  if (primaryKey.length) {
294
272
  colDefs.push(` PRIMARY KEY (${primaryKey.map(generator_1.quoteIdentifier).join(', ')})`);
295
273
  }
296
- const synthesizedSql = `CREATE TABLE ${(0, generator_1.quoteIdentifier)(table)} (\n${colDefs.join(',\n')}\n);`;
297
274
  return {
298
275
  table,
299
276
  columns,
@@ -308,7 +285,7 @@ class PostgresDatabase {
308
285
  })),
309
286
  primaryKey,
310
287
  indexes,
311
- sql: synthesizedSql,
288
+ sql: `CREATE TABLE ${(0, generator_1.quoteIdentifier)(table)} (\n${colDefs.join(',\n')}\n);`,
312
289
  };
313
290
  });
314
291
  }
@@ -321,8 +298,7 @@ class PostgresDatabase {
321
298
  pgWhere = (0, filters_1.convertPlaceholdersToPostgres)(where);
322
299
  params = p;
323
300
  }
324
- const sql = `SELECT COUNT(*) AS c FROM ${(0, generator_1.quoteIdentifier)(table)}${pgWhere}`;
325
- const res = await this.pool.query(sql, params);
301
+ const res = await this.pool.query(`SELECT COUNT(*) AS c FROM ${(0, generator_1.quoteIdentifier)(table)}${pgWhere}`, params);
326
302
  return Number(res.rows[0]?.c ?? 0);
327
303
  });
328
304
  }
@@ -342,12 +318,10 @@ class PostgresDatabase {
342
318
  }
343
319
  const nextParamIdx = filterParams.length + 1;
344
320
  let sql = `SELECT * FROM ${(0, generator_1.quoteIdentifier)(table)}${pgWhere}`;
345
- if (orderCol) {
321
+ if (orderCol)
346
322
  sql += ` ORDER BY ${(0, generator_1.quoteIdentifier)(orderCol)} ${orderDir}`;
347
- }
348
323
  sql += ` LIMIT $${nextParamIdx} OFFSET $${nextParamIdx + 1}`;
349
- const allParams = [...filterParams, limit, offset];
350
- const res = await this.pool.query(sql, allParams);
324
+ const res = await this.pool.query(sql, [...filterParams, limit, offset]);
351
325
  return res.rows;
352
326
  });
353
327
  }
@@ -373,10 +347,7 @@ class PostgresDatabase {
373
347
  const placeholders = fields.map((_, idx) => `$${idx + 1}`);
374
348
  const sql = `INSERT INTO ${(0, generator_1.quoteIdentifier)(table)} (${cols.join(', ')}) VALUES (${placeholders.join(', ')}) RETURNING *`;
375
349
  const res = await this.pool.query(sql, fields.map((f) => f.value));
376
- return {
377
- changes: res.rowCount ?? 1,
378
- lastInsertRowid: null,
379
- };
350
+ return { changes: res.rowCount ?? 1, lastInsertRowid: null };
380
351
  });
381
352
  }
382
353
  async insertRows(table, rows) {
@@ -402,10 +373,7 @@ class PostgresDatabase {
402
373
  const conds = where.map((w, idx) => `${(0, generator_1.quoteIdentifier)(w.column)} = $${fields.length + idx + 1}`);
403
374
  const sql = `UPDATE ${(0, generator_1.quoteIdentifier)(table)} SET ${sets.join(', ')} WHERE ${conds.join(' AND ')}`;
404
375
  const res = await this.pool.query(sql, [...fields.map((f) => f.value), ...where.map((w) => w.value)]);
405
- return {
406
- changes: res.rowCount ?? 0,
407
- lastInsertRowid: null,
408
- };
376
+ return { changes: res.rowCount ?? 0, lastInsertRowid: null };
409
377
  });
410
378
  }
411
379
  async updateRows(table, rows) {
@@ -430,10 +398,7 @@ class PostgresDatabase {
430
398
  const conds = where.map((w, idx) => `${(0, generator_1.quoteIdentifier)(w.column)} = $${idx + 1}`);
431
399
  const sql = `DELETE FROM ${(0, generator_1.quoteIdentifier)(table)} WHERE ${conds.join(' AND ')}`;
432
400
  const res = await this.pool.query(sql, where.map((w) => w.value));
433
- return {
434
- changes: res.rowCount ?? 0,
435
- lastInsertRowid: null,
436
- };
401
+ return { changes: res.rowCount ?? 0, lastInsertRowid: null };
437
402
  });
438
403
  }
439
404
  async deleteRows(table, rows) {
@@ -494,19 +459,13 @@ class PostgresDatabase {
494
459
  async saveQuery(name, sql) {
495
460
  return this.tryRun(async () => {
496
461
  const res = await this.pool.query(`INSERT INTO ${(0, generator_1.quoteIdentifier)(types_1.INTERNAL_TABLES.savedQueries)} (name, sql) VALUES ($1, $2) RETURNING id`, [name, sql]);
497
- return {
498
- changes: res.rowCount ?? 1,
499
- lastInsertRowid: Number(res.rows[0]?.id ?? null),
500
- };
462
+ return { changes: res.rowCount ?? 1, lastInsertRowid: Number(res.rows[0]?.id ?? null) };
501
463
  });
502
464
  }
503
465
  async deleteSavedQuery(id) {
504
466
  return this.tryRun(async () => {
505
467
  const res = await this.pool.query(`DELETE FROM ${(0, generator_1.quoteIdentifier)(types_1.INTERNAL_TABLES.savedQueries)} WHERE id = $1`, [Number(id)]);
506
- return {
507
- changes: res.rowCount ?? 0,
508
- lastInsertRowid: null,
509
- };
468
+ return { changes: res.rowCount ?? 0, lastInsertRowid: null };
510
469
  });
511
470
  }
512
471
  async getSettings() {
@@ -515,11 +474,10 @@ class PostgresDatabase {
515
474
  const settings = {};
516
475
  try {
517
476
  const res = await this.pool.query(`SELECT name, setting FROM pg_settings WHERE name = ANY($1::text[])`, [keys]);
518
- for (const row of res.rows) {
477
+ for (const row of res.rows)
519
478
  settings[row.name] = String(row.setting);
520
- }
521
479
  }
522
- catch (err) {
480
+ catch {
523
481
  try {
524
482
  const ver = await this.pool.query('SHOW server_version');
525
483
  settings['server_version'] = String(ver.rows[0]?.server_version);
@@ -610,11 +568,7 @@ class PostgresDatabase {
610
568
  for (const [tbl, refs] of byTable.entries()) {
611
569
  try {
612
570
  const countRes = await this.pool.query(`SELECT COUNT(*) AS c FROM ${(0, generator_1.quoteIdentifier)(tbl)} WHERE ${refs.map((r) => `${(0, generator_1.quoteIdentifier)(r.from)} IS NOT NULL`).join(' OR ')}`);
613
- results.push({
614
- table: tbl,
615
- refs,
616
- refCount: Number(countRes.rows[0]?.c ?? 0),
617
- });
571
+ results.push({ table: tbl, refs, refCount: Number(countRes.rows[0]?.c ?? 0) });
618
572
  }
619
573
  catch {
620
574
  results.push({ table: tbl, refs, refCount: 0 });
@@ -669,12 +623,10 @@ class PostgresDatabase {
669
623
  await this.pool.query(`ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} ALTER COLUMN ${(0, generator_1.quoteIdentifier)(colToModify)} ${action};`);
670
624
  }
671
625
  if (newColDef.defaultValue !== undefined) {
672
- if (newColDef.defaultValue === null || newColDef.defaultValue === '') {
673
- await this.pool.query(`ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} ALTER COLUMN ${(0, generator_1.quoteIdentifier)(colToModify)} DROP DEFAULT;`);
674
- }
675
- else {
676
- await this.pool.query(`ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} ALTER COLUMN ${(0, generator_1.quoteIdentifier)(colToModify)} SET DEFAULT ${newColDef.defaultValue};`);
677
- }
626
+ const action = newColDef.defaultValue === null || newColDef.defaultValue === ''
627
+ ? 'DROP DEFAULT'
628
+ : `SET DEFAULT ${newColDef.defaultValue}`;
629
+ await this.pool.query(`ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} ALTER COLUMN ${(0, generator_1.quoteIdentifier)(colToModify)} ${action};`);
678
630
  }
679
631
  if (newColDef.unique !== undefined) {
680
632
  const idxName = `idx_${table}_${colToModify}_unique`;
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export{createRouter,type AppOptions} from './app';export{createLogger,type Logger,type LogLevel} from './utils/logger';export{c,supportsColor} from './utils/colors';export{SqliteDatabase,PostgresDatabase,type IDatabase,type DatabaseDialect,type PostgresOptions,type MutationResult,type QueryOptions,type Result,type TableInfoData,type ColumnInfo,type ForeignKeyInfo,type WhereClause,type IndexInfo,type SchemaInfo,type ColumnDetail,type SavedQuery,type RowFilters,type FilterCondition,type FilterValue,type SQLInputValue,} from './db/index';export{DbManager,type DbManagerOptions,type DatabaseEntry} from './db/manager';export{type ColumnDef,type IndexDef,} from './sql/generator';export{type ColumnPlan,type ColumnGeneratorConfig,type GeneratorStrategyId,type StrategyDescriptor,type GenerateResult,} from './data/index';export{type AuthConfig,type ResolvedAuthConfig,resolveAuthConfig,getOrCreatePersistentSecret,createSessionToken,verifySessionToken,parseCookies,constantTimeCompare,hashPassword,verifyPassword,DEFAULT_USERNAME,DEFAULT_PASSWORD_HASH,SESSION_COOKIE_NAME,} from './auth/index';export{isServerlessEnvironment,createServerlessHandler,createLambdaHandler,type LambdaProxyResult,} from './serverless';export{sniffMimeType,generateHexDump,analyzeBlob,isJsonString,formatJsonSafely,type MimeAnalysis,type HexDumpLine,type HexDumpResult,type BlobMetadata,} from './utils/datatype';export * from './types/api';
1
+ export{createRouter,type AppOptions} from './app';export{createLogger,type Logger,type LogLevel} from './utils/logger';export{c,supportsColor} from './utils/colors';export{SqliteDatabase,PostgresDatabase,type IDatabase,type DatabaseDialect,type PostgresOptions,type MutationResult,type QueryOptions,type Result,type TableInfoData,type ColumnInfo,type ForeignKeyInfo,type WhereClause,type IndexInfo,type SchemaInfo,type ColumnDetail,type SavedQuery,type RowFilters,type FilterCondition,type FilterValue,type SQLInputValue} from './db/index';export{DbManager,type DbManagerOptions,type DatabaseEntry} from './db/manager';export{type ColumnDef,type IndexDef} from './sql/generator';export{type ColumnPlan,type ColumnGeneratorConfig,type GeneratorStrategyId,type StrategyDescriptor,type GenerateResult} from './data/index';export{type AuthConfig,type ResolvedAuthConfig,resolveAuthConfig,getOrCreatePersistentSecret,createSessionToken,verifySessionToken,parseCookies,constantTimeCompare,hashPassword,verifyPassword,DEFAULT_USERNAME,DEFAULT_PASSWORD_HASH,SESSION_COOKIE_NAME} from './auth/index';export{isServerlessEnvironment,createServerlessHandler,createLambdaHandler,type LambdaProxyResult} from './serverless';export{sniffMimeType,generateHexDump,analyzeBlob,isJsonString,formatJsonSafely,type MimeAnalysis,type HexDumpLine,type HexDumpResult,type BlobMetadata} from './utils/datatype';export * from './types/api';