latticesql 1.13.10 → 1.14.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.
package/README.md CHANGED
@@ -2096,7 +2096,7 @@ The convergence means you don't need to duplicate entity-context definitions in
2096
2096
  - **Dashboard** (`#/`) — one card per first-class entity with live row counts.
2097
2097
  - **Table view** (`#/objects/<entity>`) — intrinsic columns, `belongsTo` chips, and a column per junction this entity participates in.
2098
2098
  - **Detail view** (`#/objects/<entity>/<id>`) — read mode by default; `Edit` flips cells into inputs (`Save` PATCHes, `Cancel` reverts).
2099
- - **Data Model** (`#/settings/data-model`) — entity-level graph plus a side panel for adding / removing junction-table links between rows.
2099
+ - **Data Model** (inside **Database Settings**, v1.14+) — entity-level graph including the native `files`/`secrets` objects, with a per-entity editor. On a team cloud each table you own carries a **Share with team / Unshare** toggle. (Pre-1.14 this was a separate `#/settings/data-model` nav item; that hash still resolves for back-compat.)
2100
2100
 
2101
2101
  **Internal tables added on first open**
2102
2102
 
@@ -2112,18 +2112,22 @@ These tables are prefixed with `_lattice_gui_` and are hidden from `/api/entitie
2112
2112
 
2113
2113
  **HTTP surface** (all routes scoped to `http://127.0.0.1:<port>/api`):
2114
2114
 
2115
- | Route | Method | Lattice call |
2116
- | -------------------------- | ------ | ----------------------------- |
2117
- | `/project` | GET | (config + manifest summary) |
2118
- | `/entities` | GET | tables + `db.count` per table |
2119
- | `/graph` | GET | (schema graph for Data Model) |
2120
- | `/tables/:table/rows` | GET | `db.query(table, …)` |
2121
- | `/tables/:table/rows` | POST | `db.insert(table, body)` |
2122
- | `/tables/:table/rows/:id` | GET | `db.get(table, id)` |
2123
- | `/tables/:table/rows/:id` | PATCH | `db.update(table, id, body)` |
2124
- | `/tables/:table/rows/:id` | DELETE | `db.delete(table, id)` |
2125
- | `/tables/:junction/link` | POST | `db.link(junction, body)` |
2126
- | `/tables/:junction/unlink` | POST | `db.unlink(junction, body)` |
2115
+ | Route | Method | Lattice call |
2116
+ | ------------------------------ | ------ | --------------------------------------------------------------- |
2117
+ | `/project` | GET | (config + manifest summary) |
2118
+ | `/entities` | GET | tables + `db.count` per table |
2119
+ | `/graph` | GET | (schema graph for Data Model) |
2120
+ | `/tables/:table/rows` | GET | `db.query(table, …)` |
2121
+ | `/tables/:table/rows` | POST | `db.insert(table, body)` |
2122
+ | `/tables/:table/rows/:id` | GET | `db.get(table, id)` |
2123
+ | `/tables/:table/rows/:id` | PATCH | `db.update(table, id, body)` |
2124
+ | `/tables/:table/rows/:id` | DELETE | `db.delete(table, id)` |
2125
+ | `/tables/:junction/link` | POST | `db.link(junction, body)` |
2126
+ | `/tables/:junction/unlink` | POST | `db.unlink(junction, body)` |
2127
+ | `/schema/entities` | POST | create a new entity/table |
2128
+ | `/schema/entities/:name/share` | POST | share/unshare a table you own with the team (cloud, owner-only) |
2129
+
2130
+ On a team cloud, `/entities` and `/graph` (and the queryable `/tables/*` allowlist) are filtered to the tables you own plus tables shared to the team — so the API surface matches exactly what the GUI shows; a table you can't see is not reachable. `/entities` rows carry `shared` / `ownedByMe` flags in that mode.
2127
2131
 
2128
2132
  The server only binds to `127.0.0.1` and has no authentication. See [SECURITY.md](./SECURITY.md) for the threat model — do not expose this port to a non-loopback interface.
2129
2133
 
@@ -2150,6 +2154,18 @@ registerNativeEntities(db);
2150
2154
  await db.init();
2151
2155
  ```
2152
2156
 
2157
+ `isNativeEntity(name)` / `NATIVE_ENTITY_NAMES` are the single source of truth for "is this table a framework-shipped native object?" — adding a key to `NATIVE_ENTITY_DEFS` flows everywhere automatically (table creation, GUI surfacing, recognition).
2158
+
2159
+ **Adopting an existing `files`/`secrets` table (v1.14+).** If a database already has its own `files` or `secrets` table — possibly with a different/legacy column shape — `adoptNativeEntities(db)` (run after `init()`) labels that physical table as THE native object instead of duplicating it: it merges the native column superset non-destructively (`CREATE TABLE IF NOT EXISTS` + `ADD COLUMN IF NOT EXISTS`, never dropping data) and records the binding in an internal `__lattice_native_entities` registry. Legacy plaintext `secrets.value` rows stay readable (decrypt passes non-`enc:` values through) and new writes encrypt. `listNativeBindings(db)` reads the bindings. The GUI runs this automatically on every open and exposes the bindings at `GET /api/native-entities`.
2160
+
2161
+ ```ts
2162
+ import { adoptNativeEntities, listNativeBindings } from 'latticesql';
2163
+
2164
+ await db.init();
2165
+ await adoptNativeEntities(db); // merge + label existing files/secrets as native
2166
+ const bindings = await listNativeBindings(db); // [{ entity, tableName, origin }]
2167
+ ```
2168
+
2153
2169
  **Machine-local user config at `~/.lattice/` (v1.12+).** A small set of files outside any Lattice DB so a user's identity, encrypted master key, saved cloud-DB credentials, and per-team bearer tokens survive switching projects:
2154
2170
 
2155
2171
  | File | Purpose |
@@ -2222,7 +2238,9 @@ The cloud rejects redemption if the caller's claimed email doesn't match the inv
2222
2238
 
2223
2239
  **Other subcommands** (`lattice teams help` for the full list): `list`, `members`, `leave`, `destroy`, `share`, `unshare`, `shared`, `sync`, `link`, `unlink`, `pull`, `push`, `status`.
2224
2240
 
2225
- **Same flows from the GUI.** The local `lattice gui` Project Config view drives the entire teams lifecycle create / join, invite by email, share tables, link rows, see sync status. Identity (display name + email) comes from `~/.lattice/identity.json` and is prefilled in every modal.
2241
+ **Per-table ownership + opt-in sharing (v1.14+).** Team members share one physical Postgres, so visibility is enforced at the app layer via a `__lattice_object_owners` table: each table records its creator, and a user sees only the tables they own plus tables explicitly shared to the team. The native `files`/`secrets` objects are owned by the database creator and private by default. Sharing is an explicit, owner-only action (not a side effect of creating a table). The filter gates API access, not just the display.
2242
+
2243
+ **Same flows from the GUI (v1.14+).** The local `lattice gui` drives the entire teams lifecycle from **Database Settings**: rename (owner-only), invite by email (owner-only), the inline Members list (the owner is always shown as `creator`; your own row offers Leave/Destroy; non-owners can't kick), share/unshare from the Data Model, and sync status. Member admin is resolved from `GET /api/dbconfig` against the active cloud DB, so it works even when the team cloud itself is the active database. Identity (display name + email) comes from `~/.lattice/identity.json` and is locked in the Join modal. Leaving a team removes the local config + credential and switches you to another database.
2226
2244
 
2227
2245
  **Joining via the GUI is one click (v1.13.7+).** When you click "Join via invite" and the redeem succeeds, the team's cloud URL is automatically saved as a switchable database credential and a sibling YAML config is written to your project directory. The new entry shows up in the database dropdown as `<team-name>.config`. Clicking it opens the SPA with the team's shared tables already populated — no YAML editing, no `db.define()` calls.
2228
2246
 
@@ -2593,14 +2611,40 @@ interface AutoUpdateResult {
2593
2611
 
2594
2612
  ## Telemetry
2595
2613
 
2596
- `latticesql` installs and runs with **zero telemetry network calls**. No postinstall pings, no runtime beacons, no anonymous-ID files written to your home directory. The only outbound requests the package ever makes are the explicit, caller-invoked `checkForUpdate()` / `autoUpdate()` calls to `registry.npmjs.org` — and you only get those if you call them.
2614
+ `latticesql` includes [Scarf](https://scarf.sh) install analytics so we can understand how the package is used in the wild what versions are running, on what platforms, at roughly what scale. This signal is what lets us prioritize fixes, deprecations, and new features against real usage instead of guesswork.
2615
+
2616
+ **What is sent — once, at `npm install` time, by the `@scarf/scarf` postinstall hook:**
2617
+
2618
+ - Package name + version (e.g. `latticesql@1.13.6`)
2619
+ - Node.js version, OS, CPU architecture
2620
+ - A coarse, non-identifying hash derived from the install host (Scarf's default — used for deduplication, not identification)
2621
+ - The public IP of the install request (visible to any HTTPS endpoint; not stored long-term by Scarf)
2597
2622
 
2598
- To understand who's using the package we rely on two passive signals that require no instrumentation in your install or your runtime:
2623
+ **What is NOT sent:**
2599
2624
 
2600
- - **A 1×1 tracking pixel** embedded at the bottom of this README, served by [Scarf](https://scarf.sh). It fires when this README is rendered (e.g. on the npmjs.com package page). It sees only what any HTTPS image request sees — the requester's user-agent and IP, which Scarf de-identifies into coarse geo/company aggregates. Block it with any standard ad-blocker, or use a privacy-focused npm UI that doesn't render images, and Scarf sees nothing.
2601
- - **Public npm download counts**, queried by us from npm's own [downloads API](https://api.npmjs.org/downloads/range/last-month/latticesql). These are the same counts npmjs.com itself publishes — no per-user data, just aggregate package downloads.
2625
+ - No data from your application code, schemas, rows, or query strings
2626
+ - No environment variables, file paths, hostnames, or usernames
2627
+ - No runtime telemetry — `latticesql` makes zero outbound telemetry calls after install. The only network requests it makes at runtime are the explicit `checkForUpdate()` / `autoUpdate()` calls to `registry.npmjs.org`, which you opt into by calling them.
2602
2628
 
2603
- Neither signal touches your code, your data, your environment, or your install pipeline. If your network blocks `static.scarf.sh`, the README still renders (image alt text is empty); installs and runtime behavior are identical.
2629
+ **How to opt out** any one of these suppresses the install ping:
2630
+
2631
+ ```bash
2632
+ # Per-install (recommended for CI):
2633
+ SCARF_ANALYTICS=false npm install latticesql
2634
+
2635
+ # Or, project-wide (add to .npmrc):
2636
+ scarf-analytics=false
2637
+
2638
+ # Or, the cross-tool standard:
2639
+ DO_NOT_TRACK=1 npm install latticesql
2640
+
2641
+ # Or, disable all postinstall scripts entirely:
2642
+ npm install latticesql --ignore-scripts
2643
+ ```
2644
+
2645
+ Opting out has no effect on functionality — the package works identically. The Scarf postinstall is a fire-and-forget HTTPS ping with a short timeout; even when enabled it cannot fail your install.
2646
+
2647
+ See Scarf's own [privacy documentation](https://docs.scarf.sh) for the upstream policy.
2604
2648
 
2605
2649
  ---
2606
2650
 
@@ -2619,7 +2663,3 @@ See [CHANGELOG.md](./CHANGELOG.md) for the full history.
2619
2663
  ## License
2620
2664
 
2621
2665
  [Apache 2.0](./LICENSE) — includes explicit patent grant (Section 3).
2622
-
2623
- <!-- Scarf README pixel — see § Telemetry above for what it does and how to block it. -->
2624
-
2625
- ![](https://static.scarf.sh/a.png?x-pxid=bcbfdaa1-ef11-455a-bcc8-3ec215709da4)