latticesql 1.13.1 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/cli.js +38 -15
- package/dist/index.cjs +8 -1
- package/dist/index.js +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2082,6 +2082,10 @@ npx lattice gui --config ./lattice.config.yml --output ./context --port 4317
|
|
|
2082
2082
|
|
|
2083
2083
|
The convergence means you don't need to duplicate entity-context definitions in YAML for the GUI to find rendered files.
|
|
2084
2084
|
|
|
2085
|
+
**Database wizard form (v1.13.2+).** The Postgres connection form (used by Migrate to cloud + Connect to existing cloud) disables browser autocapitalize, autocorrect, and spellcheck on every text input, and trims whitespace on every read. This avoids silent failure modes where macOS Safari / iOS turned a Supabase tenant user `postgres.<ref>` into `Postgres.<ref>` on submit, and where pasted credentials carrying a trailing newline produced opaque "zero-length delimiter identifier" or SCRAM-mismatch errors. `probeCloud` also folds SQLSTATE + `routine` into `result.error` so the GUI's "Unreachable: …" surface is actionable.
|
|
2086
|
+
|
|
2087
|
+
**Switch vs. migrate (v1.13.2+ wording).** "Connect to existing cloud" _switches_ the project's `db:` line to point at the cloud; the local SQLite file stays on disk and you can switch back by editing the YAML or via the Databases catalog under User Config. Use "Migrate to cloud" only when you want to _push_ the local data into a fresh empty target.
|
|
2088
|
+
|
|
2085
2089
|
**Views**
|
|
2086
2090
|
|
|
2087
2091
|
- **Dashboard** (`#/`) — one card per first-class entity with live row counts.
|
package/dist/cli.js
CHANGED
|
@@ -7999,27 +7999,39 @@ var guiAppHtml = `<!doctype html>
|
|
|
7999
7999
|
|
|
8000
8000
|
function postgresFormHtml(prefill) {
|
|
8001
8001
|
prefill = prefill || {};
|
|
8002
|
+
// autocapitalize="off" + autocorrect="off" + spellcheck="false" keep
|
|
8003
|
+
// mobile / macOS keyboards from "helpfully" capitalizing the first
|
|
8004
|
+
// letter of usernames + host fragments. Supabase tenant users
|
|
8005
|
+
// (postgres.<ref>) are case-sensitive and silently failed
|
|
8006
|
+
// authentication when iOS Safari turned the leading "p" into "P".
|
|
8007
|
+
var attrs = ' autocapitalize="off" autocorrect="off" spellcheck="false"';
|
|
8002
8008
|
return (
|
|
8003
8009
|
'<div class="grid" style="display:grid;grid-template-columns:repeat(2,1fr);gap:8px">' +
|
|
8004
|
-
'<div><label class="field-label">Label</label><input type="text" id="w-label" placeholder="atlas" value="' + escapeHtml(prefill.label || '') + '" style="width:100%"></div>' +
|
|
8005
|
-
'<div><label class="field-label">Host</label><input type="text" id="w-host" placeholder="db.example.com" value="' + escapeHtml(prefill.host || '') + '" style="width:100%"></div>' +
|
|
8010
|
+
'<div><label class="field-label">Label</label><input type="text" id="w-label" placeholder="atlas" value="' + escapeHtml(prefill.label || '') + '" style="width:100%"' + attrs + '></div>' +
|
|
8011
|
+
'<div><label class="field-label">Host</label><input type="text" id="w-host" placeholder="db.example.com" value="' + escapeHtml(prefill.host || '') + '" style="width:100%"' + attrs + '></div>' +
|
|
8006
8012
|
'<div><label class="field-label">Port</label><input type="number" id="w-port" placeholder="5432" value="' + escapeHtml(String(prefill.port || 5432)) + '" style="width:100%"></div>' +
|
|
8007
|
-
'<div><label class="field-label">Database name</label><input type="text" id="w-dbname" placeholder="app" value="' + escapeHtml(prefill.dbname || '') + '" style="width:100%"></div>' +
|
|
8008
|
-
'<div><label class="field-label">User</label><input type="text" id="w-user" placeholder="lattice_user" value="' + escapeHtml(prefill.user || '') + '" style="width:100%"></div>' +
|
|
8009
|
-
'<div><label class="field-label">Password</label><input type="password" id="w-password" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" style="width:100%"></div>' +
|
|
8013
|
+
'<div><label class="field-label">Database name</label><input type="text" id="w-dbname" placeholder="app" value="' + escapeHtml(prefill.dbname || '') + '" style="width:100%"' + attrs + '></div>' +
|
|
8014
|
+
'<div><label class="field-label">User</label><input type="text" id="w-user" placeholder="lattice_user" value="' + escapeHtml(prefill.user || '') + '" style="width:100%"' + attrs + '></div>' +
|
|
8015
|
+
'<div><label class="field-label">Password</label><input type="password" id="w-password" placeholder="\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" style="width:100%"' + attrs + '></div>' +
|
|
8010
8016
|
'</div>'
|
|
8011
8017
|
);
|
|
8012
8018
|
}
|
|
8013
8019
|
|
|
8014
8020
|
function readPostgresWizardForm() {
|
|
8021
|
+
// Every text field is trimmed \u2014 pasted credentials frequently carry a
|
|
8022
|
+
// trailing newline or leading space that breaks URL construction
|
|
8023
|
+
// (zero-length identifier errors from the Postgres parser) or SCRAM
|
|
8024
|
+
// auth (silent password mismatch). Trim once, here, so every caller
|
|
8025
|
+
// benefits.
|
|
8026
|
+
var get = function (id) { return (document.getElementById(id).value || '').trim(); };
|
|
8015
8027
|
return {
|
|
8016
8028
|
type: 'postgres',
|
|
8017
|
-
label: (
|
|
8018
|
-
host: (
|
|
8029
|
+
label: get('w-label'),
|
|
8030
|
+
host: get('w-host'),
|
|
8019
8031
|
port: Number(document.getElementById('w-port').value || 5432),
|
|
8020
|
-
dbname: (
|
|
8021
|
-
user:
|
|
8022
|
-
password:
|
|
8032
|
+
dbname: get('w-dbname'),
|
|
8033
|
+
user: get('w-user'),
|
|
8034
|
+
password: get('w-password'),
|
|
8023
8035
|
};
|
|
8024
8036
|
}
|
|
8025
8037
|
|
|
@@ -8054,10 +8066,14 @@ var guiAppHtml = `<!doctype html>
|
|
|
8054
8066
|
function showConnectExistingModal(onClose) {
|
|
8055
8067
|
var bodyHtml =
|
|
8056
8068
|
'<p style="margin:0 0 12px;font-size:13px;color:var(--text-muted)">' +
|
|
8057
|
-
'
|
|
8058
|
-
'Your local SQLite
|
|
8059
|
-
'
|
|
8060
|
-
'
|
|
8069
|
+
'Switch this project to an <strong>existing</strong> cloud Postgres. ' +
|
|
8070
|
+
'Your local SQLite file is preserved \u2014 only this project\\'s active ' +
|
|
8071
|
+
'connection changes. Switch back any time by editing ' +
|
|
8072
|
+
'<code>lattice.config.yml</code>\\'s <code>db:</code> line or via the ' +
|
|
8073
|
+
'Databases catalog under User Config. If you want to <em>push</em> ' +
|
|
8074
|
+
'your local rows into the target instead, use Migrate to cloud. If ' +
|
|
8075
|
+
'the target is a teams DB you\\'ll be asked for an invite token ' +
|
|
8076
|
+
'after the probe.' +
|
|
8061
8077
|
'</p>' +
|
|
8062
8078
|
postgresFormHtml({}) +
|
|
8063
8079
|
'<div id="w-team-zone" style="margin-top:10px"></div>' +
|
|
@@ -9748,11 +9764,18 @@ async function probeCloud(targetUrl) {
|
|
|
9748
9764
|
}
|
|
9749
9765
|
return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
|
|
9750
9766
|
} catch (e) {
|
|
9767
|
+
const err = e;
|
|
9768
|
+
const parts = [];
|
|
9769
|
+
if (err.code) parts.push(`[${err.code}]`);
|
|
9770
|
+
if (err.message) parts.push(err.message);
|
|
9771
|
+
if (err.routine && !err.message.includes(err.routine)) {
|
|
9772
|
+
parts.push(`(routine: ${err.routine})`);
|
|
9773
|
+
}
|
|
9751
9774
|
return {
|
|
9752
9775
|
reachable: false,
|
|
9753
9776
|
dialect,
|
|
9754
9777
|
teamEnabled: false,
|
|
9755
|
-
error:
|
|
9778
|
+
error: parts.join(" ") || "unknown"
|
|
9756
9779
|
};
|
|
9757
9780
|
} finally {
|
|
9758
9781
|
if (probe) {
|
package/dist/index.cjs
CHANGED
|
@@ -5730,11 +5730,18 @@ async function probeCloud(targetUrl) {
|
|
|
5730
5730
|
}
|
|
5731
5731
|
return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
|
|
5732
5732
|
} catch (e) {
|
|
5733
|
+
const err = e;
|
|
5734
|
+
const parts = [];
|
|
5735
|
+
if (err.code) parts.push(`[${err.code}]`);
|
|
5736
|
+
if (err.message) parts.push(err.message);
|
|
5737
|
+
if (err.routine && !err.message.includes(err.routine)) {
|
|
5738
|
+
parts.push(`(routine: ${err.routine})`);
|
|
5739
|
+
}
|
|
5733
5740
|
return {
|
|
5734
5741
|
reachable: false,
|
|
5735
5742
|
dialect,
|
|
5736
5743
|
teamEnabled: false,
|
|
5737
|
-
error:
|
|
5744
|
+
error: parts.join(" ") || "unknown"
|
|
5738
5745
|
};
|
|
5739
5746
|
} finally {
|
|
5740
5747
|
if (probe) {
|
package/dist/index.js
CHANGED
|
@@ -5658,11 +5658,18 @@ async function probeCloud(targetUrl) {
|
|
|
5658
5658
|
}
|
|
5659
5659
|
return teamName !== void 0 ? { reachable: true, dialect, teamEnabled, teamName } : { reachable: true, dialect, teamEnabled };
|
|
5660
5660
|
} catch (e) {
|
|
5661
|
+
const err = e;
|
|
5662
|
+
const parts = [];
|
|
5663
|
+
if (err.code) parts.push(`[${err.code}]`);
|
|
5664
|
+
if (err.message) parts.push(err.message);
|
|
5665
|
+
if (err.routine && !err.message.includes(err.routine)) {
|
|
5666
|
+
parts.push(`(routine: ${err.routine})`);
|
|
5667
|
+
}
|
|
5661
5668
|
return {
|
|
5662
5669
|
reachable: false,
|
|
5663
5670
|
dialect,
|
|
5664
5671
|
teamEnabled: false,
|
|
5665
|
-
error:
|
|
5672
|
+
error: parts.join(" ") || "unknown"
|
|
5666
5673
|
};
|
|
5667
5674
|
} finally {
|
|
5668
5675
|
if (probe) {
|
package/package.json
CHANGED