latticesql 3.3.3 → 3.3.4
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/dist/cli.js +62 -9
- package/dist/index.cjs +61 -8
- package/dist/index.js +61 -8
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1061,13 +1061,24 @@ function moduleContext() {
|
|
|
1061
1061
|
return _moduleContext;
|
|
1062
1062
|
}
|
|
1063
1063
|
async function registerPostgresPolyfills(run) {
|
|
1064
|
+
let permissionDenied = false;
|
|
1064
1065
|
for (const { warn, sql } of POSTGRES_POLYFILLS) {
|
|
1065
1066
|
try {
|
|
1066
1067
|
await run(sql);
|
|
1067
1068
|
} catch (err) {
|
|
1068
|
-
|
|
1069
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1070
|
+
if (/permission denied/i.test(msg)) {
|
|
1071
|
+
permissionDenied = true;
|
|
1072
|
+
} else {
|
|
1073
|
+
console.warn(`[PostgresAdapter] ${warn}`, msg);
|
|
1074
|
+
}
|
|
1069
1075
|
}
|
|
1070
1076
|
}
|
|
1077
|
+
if (permissionDenied) {
|
|
1078
|
+
console.debug(
|
|
1079
|
+
"[PostgresAdapter] SQLite-compat polyfills are owner-managed on this cloud; skipping member-side (re)creation (expected)."
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1071
1082
|
}
|
|
1072
1083
|
function translateDialect(sql) {
|
|
1073
1084
|
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
@@ -5103,7 +5114,23 @@ var init_lattice = __esm({
|
|
|
5103
5114
|
}
|
|
5104
5115
|
/** Async tail of init(). See {@link init} for the sync-validation phase. */
|
|
5105
5116
|
async _initAsync(options) {
|
|
5106
|
-
|
|
5117
|
+
let introspectOnly = options.introspectOnly === true;
|
|
5118
|
+
if (!introspectOnly && this.getDialect() === "postgres") {
|
|
5119
|
+
try {
|
|
5120
|
+
const [marker, role] = await Promise.all([
|
|
5121
|
+
getAsyncOrSync(this._adapter, `SELECT to_regclass('__lattice_owners') AS reg`),
|
|
5122
|
+
getAsyncOrSync(
|
|
5123
|
+
this._adapter,
|
|
5124
|
+
`SELECT rolcreaterole FROM pg_roles WHERE rolname = current_user`
|
|
5125
|
+
)
|
|
5126
|
+
]);
|
|
5127
|
+
const provisioned = !!marker && marker.reg != null;
|
|
5128
|
+
const canCreateRoles = !!role && role.rolcreaterole === true;
|
|
5129
|
+
introspectOnly = provisioned && !canCreateRoles;
|
|
5130
|
+
} catch {
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
if (introspectOnly) {
|
|
5107
5134
|
for (const tableName of this._schema.getTables().keys()) {
|
|
5108
5135
|
try {
|
|
5109
5136
|
const cols = await introspectColumnsAsyncOrSync(this._adapter, tableName);
|
|
@@ -57051,7 +57078,7 @@ var appJs = `
|
|
|
57051
57078
|
'<div class="view-header">' +
|
|
57052
57079
|
'<span class="entity-icon">\u2699</span>' +
|
|
57053
57080
|
'<h1>' + escapeHtml(tableName) + '</h1>' +
|
|
57054
|
-
'<span class="count">' + entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's') +
|
|
57081
|
+
'<span class="count">' + (entry.rowCount == null ? 'no access' : (entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's'))) +
|
|
57055
57082
|
' \xB7 read-only</span>' +
|
|
57056
57083
|
'</div>' +
|
|
57057
57084
|
'<div class="muted" style="margin-bottom:12px;font-size:13px;">' +
|
|
@@ -61804,6 +61831,14 @@ async function reconcileCloudMemberAccess(db) {
|
|
|
61804
61831
|
);
|
|
61805
61832
|
}
|
|
61806
61833
|
}
|
|
61834
|
+
await runAsyncOrSync(
|
|
61835
|
+
db.adapter,
|
|
61836
|
+
`DO $LATTICE$ BEGIN
|
|
61837
|
+
IF to_regclass('__lattice_changelog') IS NOT NULL THEN
|
|
61838
|
+
EXECUTE 'GRANT SELECT, INSERT ON "__lattice_changelog" TO ${MEMBER_GROUP}';
|
|
61839
|
+
END IF;
|
|
61840
|
+
END $LATTICE$`
|
|
61841
|
+
);
|
|
61807
61842
|
}
|
|
61808
61843
|
async function secureNewCloudTable(db, table, pk) {
|
|
61809
61844
|
if (db.getDialect() !== "postgres") return;
|
|
@@ -65337,6 +65372,7 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
65337
65372
|
]);
|
|
65338
65373
|
const views = viewsRaw;
|
|
65339
65374
|
const knownTables = /* @__PURE__ */ new Set([...declared, ...discovered.map((t8) => t8.name)]);
|
|
65375
|
+
const memberEntityDefs = [];
|
|
65340
65376
|
for (const t8 of discovered) {
|
|
65341
65377
|
if (declared.has(t8.name)) continue;
|
|
65342
65378
|
if (t8.columns.length === 0) continue;
|
|
@@ -65344,17 +65380,25 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
65344
65380
|
discoveredJunctions.add(t8.name);
|
|
65345
65381
|
continue;
|
|
65346
65382
|
}
|
|
65347
|
-
|
|
65383
|
+
const def = {
|
|
65348
65384
|
columns: Object.fromEntries(t8.columns.map((c6) => [c6, "TEXT"])),
|
|
65349
65385
|
...t8.pk.length > 0 ? { primaryKey: t8.pk.length === 1 ? t8.pk[0] : t8.pk } : {},
|
|
65350
65386
|
render: () => "",
|
|
65351
65387
|
outputFile: `${t8.name}/.lattice/${t8.name}.md`
|
|
65352
|
-
}
|
|
65388
|
+
};
|
|
65389
|
+
db.define(t8.name, def);
|
|
65390
|
+
memberEntityDefs.push({ name: t8.name, definition: def });
|
|
65353
65391
|
}
|
|
65354
65392
|
for (const { name } of views) {
|
|
65355
65393
|
const base = name.slice(0, -2);
|
|
65356
65394
|
if (knownTables.has(base)) maskedReadViews.set(base, name);
|
|
65357
65395
|
}
|
|
65396
|
+
if (autoRender && memberEntityDefs.length > 0) {
|
|
65397
|
+
const existingContexts = db.entityContexts();
|
|
65398
|
+
for (const { table, definition } of deriveCanonicalContexts(memberEntityDefs)) {
|
|
65399
|
+
if (!existingContexts.has(table)) db.defineEntityContext(table, definition);
|
|
65400
|
+
}
|
|
65401
|
+
}
|
|
65358
65402
|
}
|
|
65359
65403
|
}
|
|
65360
65404
|
} catch {
|
|
@@ -66845,9 +66889,18 @@ async function startGuiServer(options) {
|
|
|
66845
66889
|
}
|
|
66846
66890
|
const tables = [];
|
|
66847
66891
|
for (const r6 of rows) {
|
|
66848
|
-
|
|
66849
|
-
|
|
66850
|
-
|
|
66892
|
+
try {
|
|
66893
|
+
const cols = await active.db.introspectColumns(r6.name);
|
|
66894
|
+
const rowCount = await active.db.count(r6.name);
|
|
66895
|
+
tables.push({ name: r6.name, columns: cols, rowCount });
|
|
66896
|
+
} catch (err) {
|
|
66897
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
66898
|
+
if (/permission denied|does not exist/i.test(msg)) {
|
|
66899
|
+
tables.push({ name: r6.name, columns: [], rowCount: null });
|
|
66900
|
+
} else {
|
|
66901
|
+
throw err;
|
|
66902
|
+
}
|
|
66903
|
+
}
|
|
66851
66904
|
}
|
|
66852
66905
|
sendJson(res, { tables });
|
|
66853
66906
|
return;
|
|
@@ -67813,7 +67866,7 @@ function printHelp() {
|
|
|
67813
67866
|
);
|
|
67814
67867
|
}
|
|
67815
67868
|
function getVersion() {
|
|
67816
|
-
if (true) return "3.3.
|
|
67869
|
+
if (true) return "3.3.4";
|
|
67817
67870
|
try {
|
|
67818
67871
|
const pkgPath = new URL("../package.json", import.meta.url).pathname;
|
|
67819
67872
|
const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
|
package/dist/index.cjs
CHANGED
|
@@ -437,13 +437,24 @@ function moduleContext() {
|
|
|
437
437
|
return _moduleContext;
|
|
438
438
|
}
|
|
439
439
|
async function registerPostgresPolyfills(run) {
|
|
440
|
+
let permissionDenied = false;
|
|
440
441
|
for (const { warn, sql } of POSTGRES_POLYFILLS) {
|
|
441
442
|
try {
|
|
442
443
|
await run(sql);
|
|
443
444
|
} catch (err) {
|
|
444
|
-
|
|
445
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
446
|
+
if (/permission denied/i.test(msg)) {
|
|
447
|
+
permissionDenied = true;
|
|
448
|
+
} else {
|
|
449
|
+
console.warn(`[PostgresAdapter] ${warn}`, msg);
|
|
450
|
+
}
|
|
445
451
|
}
|
|
446
452
|
}
|
|
453
|
+
if (permissionDenied) {
|
|
454
|
+
console.debug(
|
|
455
|
+
"[PostgresAdapter] SQLite-compat polyfills are owner-managed on this cloud; skipping member-side (re)creation (expected)."
|
|
456
|
+
);
|
|
457
|
+
}
|
|
447
458
|
}
|
|
448
459
|
function translateDialect(sql) {
|
|
449
460
|
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
@@ -5266,7 +5277,23 @@ var init_lattice = __esm({
|
|
|
5266
5277
|
}
|
|
5267
5278
|
/** Async tail of init(). See {@link init} for the sync-validation phase. */
|
|
5268
5279
|
async _initAsync(options) {
|
|
5269
|
-
|
|
5280
|
+
let introspectOnly = options.introspectOnly === true;
|
|
5281
|
+
if (!introspectOnly && this.getDialect() === "postgres") {
|
|
5282
|
+
try {
|
|
5283
|
+
const [marker, role] = await Promise.all([
|
|
5284
|
+
getAsyncOrSync(this._adapter, `SELECT to_regclass('__lattice_owners') AS reg`),
|
|
5285
|
+
getAsyncOrSync(
|
|
5286
|
+
this._adapter,
|
|
5287
|
+
`SELECT rolcreaterole FROM pg_roles WHERE rolname = current_user`
|
|
5288
|
+
)
|
|
5289
|
+
]);
|
|
5290
|
+
const provisioned = !!marker && marker.reg != null;
|
|
5291
|
+
const canCreateRoles = !!role && role.rolcreaterole === true;
|
|
5292
|
+
introspectOnly = provisioned && !canCreateRoles;
|
|
5293
|
+
} catch {
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
if (introspectOnly) {
|
|
5270
5297
|
for (const tableName of this._schema.getTables().keys()) {
|
|
5271
5298
|
try {
|
|
5272
5299
|
const cols = await introspectColumnsAsyncOrSync(this._adapter, tableName);
|
|
@@ -54054,6 +54081,14 @@ async function reconcileCloudMemberAccess(db) {
|
|
|
54054
54081
|
);
|
|
54055
54082
|
}
|
|
54056
54083
|
}
|
|
54084
|
+
await runAsyncOrSync(
|
|
54085
|
+
db.adapter,
|
|
54086
|
+
`DO $LATTICE$ BEGIN
|
|
54087
|
+
IF to_regclass('__lattice_changelog') IS NOT NULL THEN
|
|
54088
|
+
EXECUTE 'GRANT SELECT, INSERT ON "__lattice_changelog" TO ${MEMBER_GROUP}';
|
|
54089
|
+
END IF;
|
|
54090
|
+
END $LATTICE$`
|
|
54091
|
+
);
|
|
54057
54092
|
}
|
|
54058
54093
|
async function secureNewCloudTable(db, table, pk) {
|
|
54059
54094
|
if (db.getDialect() !== "postgres") return;
|
|
@@ -58951,7 +58986,7 @@ var appJs = `
|
|
|
58951
58986
|
'<div class="view-header">' +
|
|
58952
58987
|
'<span class="entity-icon">\u2699</span>' +
|
|
58953
58988
|
'<h1>' + escapeHtml(tableName) + '</h1>' +
|
|
58954
|
-
'<span class="count">' + entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's') +
|
|
58989
|
+
'<span class="count">' + (entry.rowCount == null ? 'no access' : (entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's'))) +
|
|
58955
58990
|
' \xB7 read-only</span>' +
|
|
58956
58991
|
'</div>' +
|
|
58957
58992
|
'<div class="muted" style="margin-bottom:12px;font-size:13px;">' +
|
|
@@ -66509,6 +66544,7 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
66509
66544
|
]);
|
|
66510
66545
|
const views = viewsRaw;
|
|
66511
66546
|
const knownTables = /* @__PURE__ */ new Set([...declared, ...discovered.map((t8) => t8.name)]);
|
|
66547
|
+
const memberEntityDefs = [];
|
|
66512
66548
|
for (const t8 of discovered) {
|
|
66513
66549
|
if (declared.has(t8.name)) continue;
|
|
66514
66550
|
if (t8.columns.length === 0) continue;
|
|
@@ -66516,17 +66552,25 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
66516
66552
|
discoveredJunctions.add(t8.name);
|
|
66517
66553
|
continue;
|
|
66518
66554
|
}
|
|
66519
|
-
|
|
66555
|
+
const def = {
|
|
66520
66556
|
columns: Object.fromEntries(t8.columns.map((c6) => [c6, "TEXT"])),
|
|
66521
66557
|
...t8.pk.length > 0 ? { primaryKey: t8.pk.length === 1 ? t8.pk[0] : t8.pk } : {},
|
|
66522
66558
|
render: () => "",
|
|
66523
66559
|
outputFile: `${t8.name}/.lattice/${t8.name}.md`
|
|
66524
|
-
}
|
|
66560
|
+
};
|
|
66561
|
+
db.define(t8.name, def);
|
|
66562
|
+
memberEntityDefs.push({ name: t8.name, definition: def });
|
|
66525
66563
|
}
|
|
66526
66564
|
for (const { name } of views) {
|
|
66527
66565
|
const base = name.slice(0, -2);
|
|
66528
66566
|
if (knownTables.has(base)) maskedReadViews.set(base, name);
|
|
66529
66567
|
}
|
|
66568
|
+
if (autoRender && memberEntityDefs.length > 0) {
|
|
66569
|
+
const existingContexts = db.entityContexts();
|
|
66570
|
+
for (const { table, definition } of deriveCanonicalContexts(memberEntityDefs)) {
|
|
66571
|
+
if (!existingContexts.has(table)) db.defineEntityContext(table, definition);
|
|
66572
|
+
}
|
|
66573
|
+
}
|
|
66530
66574
|
}
|
|
66531
66575
|
}
|
|
66532
66576
|
} catch {
|
|
@@ -68017,9 +68061,18 @@ async function startGuiServer(options) {
|
|
|
68017
68061
|
}
|
|
68018
68062
|
const tables = [];
|
|
68019
68063
|
for (const r6 of rows) {
|
|
68020
|
-
|
|
68021
|
-
|
|
68022
|
-
|
|
68064
|
+
try {
|
|
68065
|
+
const cols = await active.db.introspectColumns(r6.name);
|
|
68066
|
+
const rowCount = await active.db.count(r6.name);
|
|
68067
|
+
tables.push({ name: r6.name, columns: cols, rowCount });
|
|
68068
|
+
} catch (err) {
|
|
68069
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
68070
|
+
if (/permission denied|does not exist/i.test(msg)) {
|
|
68071
|
+
tables.push({ name: r6.name, columns: [], rowCount: null });
|
|
68072
|
+
} else {
|
|
68073
|
+
throw err;
|
|
68074
|
+
}
|
|
68075
|
+
}
|
|
68023
68076
|
}
|
|
68024
68077
|
sendJson(res, { tables });
|
|
68025
68078
|
return;
|
package/dist/index.js
CHANGED
|
@@ -430,13 +430,24 @@ function moduleContext() {
|
|
|
430
430
|
return _moduleContext;
|
|
431
431
|
}
|
|
432
432
|
async function registerPostgresPolyfills(run) {
|
|
433
|
+
let permissionDenied = false;
|
|
433
434
|
for (const { warn, sql } of POSTGRES_POLYFILLS) {
|
|
434
435
|
try {
|
|
435
436
|
await run(sql);
|
|
436
437
|
} catch (err) {
|
|
437
|
-
|
|
438
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
439
|
+
if (/permission denied/i.test(msg)) {
|
|
440
|
+
permissionDenied = true;
|
|
441
|
+
} else {
|
|
442
|
+
console.warn(`[PostgresAdapter] ${warn}`, msg);
|
|
443
|
+
}
|
|
438
444
|
}
|
|
439
445
|
}
|
|
446
|
+
if (permissionDenied) {
|
|
447
|
+
console.debug(
|
|
448
|
+
"[PostgresAdapter] SQLite-compat polyfills are owner-managed on this cloud; skipping member-side (re)creation (expected)."
|
|
449
|
+
);
|
|
450
|
+
}
|
|
440
451
|
}
|
|
441
452
|
function translateDialect(sql) {
|
|
442
453
|
if (/INSERT\s+OR\s+REPLACE\s+INTO/i.test(sql)) {
|
|
@@ -5262,7 +5273,23 @@ var init_lattice = __esm({
|
|
|
5262
5273
|
}
|
|
5263
5274
|
/** Async tail of init(). See {@link init} for the sync-validation phase. */
|
|
5264
5275
|
async _initAsync(options) {
|
|
5265
|
-
|
|
5276
|
+
let introspectOnly = options.introspectOnly === true;
|
|
5277
|
+
if (!introspectOnly && this.getDialect() === "postgres") {
|
|
5278
|
+
try {
|
|
5279
|
+
const [marker, role] = await Promise.all([
|
|
5280
|
+
getAsyncOrSync(this._adapter, `SELECT to_regclass('__lattice_owners') AS reg`),
|
|
5281
|
+
getAsyncOrSync(
|
|
5282
|
+
this._adapter,
|
|
5283
|
+
`SELECT rolcreaterole FROM pg_roles WHERE rolname = current_user`
|
|
5284
|
+
)
|
|
5285
|
+
]);
|
|
5286
|
+
const provisioned = !!marker && marker.reg != null;
|
|
5287
|
+
const canCreateRoles = !!role && role.rolcreaterole === true;
|
|
5288
|
+
introspectOnly = provisioned && !canCreateRoles;
|
|
5289
|
+
} catch {
|
|
5290
|
+
}
|
|
5291
|
+
}
|
|
5292
|
+
if (introspectOnly) {
|
|
5266
5293
|
for (const tableName of this._schema.getTables().keys()) {
|
|
5267
5294
|
try {
|
|
5268
5295
|
const cols = await introspectColumnsAsyncOrSync(this._adapter, tableName);
|
|
@@ -53867,6 +53894,14 @@ async function reconcileCloudMemberAccess(db) {
|
|
|
53867
53894
|
);
|
|
53868
53895
|
}
|
|
53869
53896
|
}
|
|
53897
|
+
await runAsyncOrSync(
|
|
53898
|
+
db.adapter,
|
|
53899
|
+
`DO $LATTICE$ BEGIN
|
|
53900
|
+
IF to_regclass('__lattice_changelog') IS NOT NULL THEN
|
|
53901
|
+
EXECUTE 'GRANT SELECT, INSERT ON "__lattice_changelog" TO ${MEMBER_GROUP}';
|
|
53902
|
+
END IF;
|
|
53903
|
+
END $LATTICE$`
|
|
53904
|
+
);
|
|
53870
53905
|
}
|
|
53871
53906
|
async function secureNewCloudTable(db, table, pk) {
|
|
53872
53907
|
if (db.getDialect() !== "postgres") return;
|
|
@@ -58771,7 +58806,7 @@ var appJs = `
|
|
|
58771
58806
|
'<div class="view-header">' +
|
|
58772
58807
|
'<span class="entity-icon">\u2699</span>' +
|
|
58773
58808
|
'<h1>' + escapeHtml(tableName) + '</h1>' +
|
|
58774
|
-
'<span class="count">' + entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's') +
|
|
58809
|
+
'<span class="count">' + (entry.rowCount == null ? 'no access' : (entry.rowCount + ' row' + (entry.rowCount === 1 ? '' : 's'))) +
|
|
58775
58810
|
' \xB7 read-only</span>' +
|
|
58776
58811
|
'</div>' +
|
|
58777
58812
|
'<div class="muted" style="margin-bottom:12px;font-size:13px;">' +
|
|
@@ -66328,6 +66363,7 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
66328
66363
|
]);
|
|
66329
66364
|
const views = viewsRaw;
|
|
66330
66365
|
const knownTables = /* @__PURE__ */ new Set([...declared, ...discovered.map((t8) => t8.name)]);
|
|
66366
|
+
const memberEntityDefs = [];
|
|
66331
66367
|
for (const t8 of discovered) {
|
|
66332
66368
|
if (declared.has(t8.name)) continue;
|
|
66333
66369
|
if (t8.columns.length === 0) continue;
|
|
@@ -66335,17 +66371,25 @@ async function openConfig(configPath, outputDir, autoRender = false, realtimeWat
|
|
|
66335
66371
|
discoveredJunctions.add(t8.name);
|
|
66336
66372
|
continue;
|
|
66337
66373
|
}
|
|
66338
|
-
|
|
66374
|
+
const def = {
|
|
66339
66375
|
columns: Object.fromEntries(t8.columns.map((c6) => [c6, "TEXT"])),
|
|
66340
66376
|
...t8.pk.length > 0 ? { primaryKey: t8.pk.length === 1 ? t8.pk[0] : t8.pk } : {},
|
|
66341
66377
|
render: () => "",
|
|
66342
66378
|
outputFile: `${t8.name}/.lattice/${t8.name}.md`
|
|
66343
|
-
}
|
|
66379
|
+
};
|
|
66380
|
+
db.define(t8.name, def);
|
|
66381
|
+
memberEntityDefs.push({ name: t8.name, definition: def });
|
|
66344
66382
|
}
|
|
66345
66383
|
for (const { name } of views) {
|
|
66346
66384
|
const base = name.slice(0, -2);
|
|
66347
66385
|
if (knownTables.has(base)) maskedReadViews.set(base, name);
|
|
66348
66386
|
}
|
|
66387
|
+
if (autoRender && memberEntityDefs.length > 0) {
|
|
66388
|
+
const existingContexts = db.entityContexts();
|
|
66389
|
+
for (const { table, definition } of deriveCanonicalContexts(memberEntityDefs)) {
|
|
66390
|
+
if (!existingContexts.has(table)) db.defineEntityContext(table, definition);
|
|
66391
|
+
}
|
|
66392
|
+
}
|
|
66349
66393
|
}
|
|
66350
66394
|
}
|
|
66351
66395
|
} catch {
|
|
@@ -67836,9 +67880,18 @@ async function startGuiServer(options) {
|
|
|
67836
67880
|
}
|
|
67837
67881
|
const tables = [];
|
|
67838
67882
|
for (const r6 of rows) {
|
|
67839
|
-
|
|
67840
|
-
|
|
67841
|
-
|
|
67883
|
+
try {
|
|
67884
|
+
const cols = await active.db.introspectColumns(r6.name);
|
|
67885
|
+
const rowCount = await active.db.count(r6.name);
|
|
67886
|
+
tables.push({ name: r6.name, columns: cols, rowCount });
|
|
67887
|
+
} catch (err) {
|
|
67888
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
67889
|
+
if (/permission denied|does not exist/i.test(msg)) {
|
|
67890
|
+
tables.push({ name: r6.name, columns: [], rowCount: null });
|
|
67891
|
+
} else {
|
|
67892
|
+
throw err;
|
|
67893
|
+
}
|
|
67894
|
+
}
|
|
67842
67895
|
}
|
|
67843
67896
|
sendJson(res, { tables });
|
|
67844
67897
|
return;
|
package/package.json
CHANGED