@rebasepro/server-postgres 0.9.1-canary.09aaf62 → 0.9.1-canary.0de22e0

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
@@ -76,6 +76,27 @@ process.on("SIGTERM", async () => {
76
76
  | `statementTimeout` | 30,000 |
77
77
  | `keepAlive` | true |
78
78
 
79
+ ## Testing
80
+
81
+ This package runs **two test runners**, split by directory. This is deliberate — check which half you are in before running anything.
82
+
83
+ | Tests | Runner | Config | Command |
84
+ |-------|--------|--------|---------|
85
+ | `test/*.ts` (unit) | jest | [`jest.config.cjs`](./jest.config.cjs) | `pnpm test` |
86
+ | `test/e2e/**` (integration) | vitest | [`vitest.e2e.config.ts`](./vitest.e2e.config.ts) | `pnpm test:e2e` |
87
+
88
+ The unit tests use jest's injected globals (`describe`/`it`/`expect`) and `jest.mock`. The e2e tests import explicitly from `vitest` and need Docker (testcontainers spins up a real Postgres).
89
+
90
+ **Running a single unit test:**
91
+
92
+ ```bash
93
+ npx jest test/auth-services.test.ts
94
+ ```
95
+
96
+ Pointing `vitest` at a unit test is the easy mistake here — it produces a bare `ReferenceError: jest is not defined` and a "no tests" result, which looks exactly like a dead or broken test file rather than the wrong runner. [`vitest.config.ts`](./vitest.config.ts) exists solely to intercept that and print the command you actually wanted.
97
+
98
+ `pnpm test` runs jest **without** `--passWithNoTests`: if the unit suite ever stops being collected, CI fails instead of going quietly green.
99
+
79
100
  ## Related Packages
80
101
 
81
102
  | Package | Role |
@@ -114,6 +114,24 @@ export declare class PostgresBackendDriver implements DataDriver {
114
114
  }): Promise<Record<string, unknown>[]>;
115
115
  fetchAvailableDatabases(): Promise<string[]>;
116
116
  fetchAvailableRoles(): Promise<string[]>;
117
+ /**
118
+ * Application-level roles actually in use in this project.
119
+ *
120
+ * Distinct from {@link fetchAvailableRoles}, which returns native
121
+ * PostgreSQL roles from `pg_roles` (`postgres`, `rebase_user`, …). Those
122
+ * are the roles the SQL editor can `SET ROLE` to. *These* are the strings
123
+ * held in the users table's `roles` column, injected per-transaction as
124
+ * `auth.roles()` and matched by `SecurityRule.roles`. Feeding the pg roles
125
+ * into a `SecurityRule.roles` field produces a condition no user can ever
126
+ * satisfy, so the two must not be conflated.
127
+ *
128
+ * Roles have no registry table — they were migrated out of
129
+ * `rebase.user_roles` onto an inline `roles TEXT[]` column — so the live
130
+ * set is derived from what is assigned. A role that is declared in a policy
131
+ * but held by nobody yet cannot be discovered here; callers that need it
132
+ * should union in the roles they already know about.
133
+ */
134
+ fetchApplicationRoles(): Promise<string[]>;
117
135
  fetchCurrentDatabase(): Promise<string | undefined>;
118
136
  /**
119
137
  * Fetch public tables that are not yet mapped to a collection.
@@ -4,7 +4,7 @@
4
4
  * Implements the `BackendBootstrapper` interface for PostgreSQL.
5
5
  */
6
6
  import { NodePgDatabase } from "drizzle-orm/node-postgres";
7
- import { BackendBootstrapper } from "@rebasepro/types";
7
+ import { BackendBootstrapper, type RealtimeChannelsConfig } from "@rebasepro/types";
8
8
  import { PostgresBackendDriver } from "./PostgresBackendDriver";
9
9
  import { RealtimeService } from "./services/realtimeService";
10
10
  import { DatabasePoolManager } from "./databasePoolManager";
@@ -25,6 +25,12 @@ export interface PostgresDriverConfig {
25
25
  * (BaaS mode). Defaults to `public`.
26
26
  */
27
27
  introspectionSchema?: string;
28
+ /**
29
+ * Realtime options. Currently only channel retention, which is opt-in:
30
+ * without rules here no channel keeps any history and broadcast stays
31
+ * fire-and-forget. See {@link ChannelRetentionRule}.
32
+ */
33
+ realtime?: RealtimeChannelsConfig;
28
34
  }
29
35
  /**
30
36
  * Opaque internals bag that PostgresBootstrapper stores during `initializeDriver()`