@everystack/server 0.4.29 → 0.4.30

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `@everystack/server` are documented here.
4
4
 
5
5
  Format based on [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [0.4.30] - 2026-09-04
8
+
9
+ ### Fixed
10
+
11
+ - ADOPT resolves its master from ADMIN_DATABASE_URL on a BYO/external RDS
12
+
7
13
  ## [0.4.29] - 2026-09-04
8
14
 
9
15
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everystack/server",
3
- "version": "0.4.29",
3
+ "version": "0.4.30",
4
4
  "description": "Server runtime primitives for Lambda — event adapters, routing, SSR, image processing",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Scalable Technology, Inc. <licensing@scalable.technology>",
@@ -187,8 +187,8 @@
187
187
  "sst": "4.13.1",
188
188
  "ts-jest": "29.4.9",
189
189
  "typescript": "5.9.3",
190
- "@everystack/cli": "0.4.71",
191
- "@everystack/auth": "0.4.4"
190
+ "@everystack/auth": "0.4.4",
191
+ "@everystack/cli": "0.4.71"
192
192
  },
193
193
  "scripts": {
194
194
  "test": "jest",
package/src/db.ts CHANGED
@@ -150,6 +150,26 @@ export function getOperatorDatabaseUrl(): { url: string; source: 'admin' | 'mast
150
150
  return null;
151
151
  }
152
152
 
153
+ /**
154
+ * The connection ADOPT (ownership reassignment) runs on: the linked SST Postgres master when one is
155
+ * present, else the `ADMIN_DATABASE_URL` operator secret.
156
+ *
157
+ * A brownfield / external-RDS app — the exact `db:pull --abilities live` audience — has NO linked
158
+ * `sst.aws.Postgres` component. It wires the database as secrets, and its `ADMIN_DATABASE_URL` is a
159
+ * privileged operator (commonly BYPASSRLS and a member of `postgres`, i.e. master-capable) that the
160
+ * ops Lambda already carries. Resolving ADOPT's master ONLY through the component dead-ended those
161
+ * apps on the missing component. This falls back to the admin secret so ADOPT has a connection to
162
+ * try. Whether that connection can ACTUALLY reassign is NOT decided here — ADOPT's live
163
+ * `master_can_act` probe decides it: a least-privilege admin resolves but the probe then refuses
164
+ * precisely (naming the grant to run), while a master-capable admin proceeds.
165
+ *
166
+ * `master` (linked component) is preferred because its presence guarantees master capability; the
167
+ * admin fallback is probe-gated. Never the least-privilege `DATABASE_URL`.
168
+ */
169
+ export function getAdoptMasterUrl(): string | null {
170
+ return getMasterDatabaseUrl() ?? getAdminDatabaseUrl();
171
+ }
172
+
153
173
  export function getJwtSecret(): Uint8Array {
154
174
  // PascalCase Secret (SST_RESOURCE_JwtSecret → { value })
155
175
  const pascal = sstLink('JwtSecret')?.value as string | undefined;
package/src/plugin.ts CHANGED
@@ -882,7 +882,7 @@ export function dbPlugin(options: DbPluginOptions): Plugin {
882
882
  actions['db:converge-ownership'] = async (payload, _ctx) => {
883
883
  const { sql } = await import('drizzle-orm');
884
884
  const { convergeOwnership } = await import('./provision');
885
- const { getMasterDatabaseUrl } = await import('./db');
885
+ const { getAdoptMasterUrl } = await import('./db');
886
886
 
887
887
  const queryRows = async (statement: string): Promise<any[]> => {
888
888
  const res: any = await opsDb.execute(sql.raw(statement));
@@ -891,10 +891,12 @@ export function dbPlugin(options: DbPluginOptions): Plugin {
891
891
  return [];
892
892
  };
893
893
 
894
- // The MASTER connection (linked RDS master), when linked — ENACT routes to it the grants the
895
- // operator cannot make, and ADOPT requires it outright. Absent on a BYO-database app: master
896
- // stays null and ADOPT refuses with the fix SQL. Opened for this invoke, closed in the finally.
897
- const masterUrl = getMasterDatabaseUrl();
894
+ // The MASTER connection ADOPT reassigns through: the linked SST Postgres master, else the
895
+ // ADMIN_DATABASE_URL operator secret (a brownfield/external-RDS app has no component but wires
896
+ // a master-capable admin — see getAdoptMasterUrl). ENACT also routes hard grants here. Null
897
+ // only when NEITHER exists; then ADOPT refuses. Whether the resolved connection can actually
898
+ // reassign is decided by ADOPT's live probe, not by which source won. Closed in the finally.
899
+ const masterUrl = getAdoptMasterUrl();
898
900
  let masterClient: any = null;
899
901
  let master: { execute: (s: string) => Promise<unknown>; query: (s: string) => Promise<any[]> } | null = null;
900
902
  if (masterUrl) {
package/src/provision.ts CHANGED
@@ -418,13 +418,15 @@ async function adoptOwners(
418
418
  const vRefusal = pgVersionRefusal(Number(vRow?.v ?? 0));
419
419
  if (vRefusal) return { ...EMPTY_ADOPTION, refusals: [vRefusal] };
420
420
 
421
- // ADOPT cannot run as the least-privilege operator (it would need INHERIT membership in the
422
- // current owner `postgres`, which is the master). No master → a precise refusal, never an attempt.
421
+ // ADOPT reassigns on a master-capable connection (the linked SST Postgres master, else the
422
+ // ADMIN_DATABASE_URL operator secret — see getAdoptMasterUrl). A connection is present unless the
423
+ // app configures NEITHER. Its actual capability is probed below; this refusal is only the
424
+ // no-connection-at-all case.
423
425
  if (!deps.master) {
424
426
  return { ...EMPTY_ADOPTION, refusals: [
425
- 'ADOPT requires the master connection — the least-privilege operator cannot reassign a ' +
426
- 'postgres-owned object. Link an sst.aws.Postgres component (the master fallback), or run the ' +
427
- 'ALTER … OWNER TO statements as the master by hand.',
427
+ 'ADOPT has no master-capable connection to reassign through. Provide an ADMIN_DATABASE_URL ' +
428
+ 'secret for the stage (a privileged operator that owns/administers the objects), or link an ' +
429
+ 'sst.aws.Postgres component. The least-privilege DATABASE_URL cannot reassign a postgres-owned object.',
428
430
  ] };
429
431
  }
430
432