@rebasepro/server-postgres 0.13.0 → 0.13.1-canary.g1822133
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/PostgresBackendDriver.d.ts +48 -1
- package/dist/PostgresBootstrapper.d.ts +26 -0
- package/dist/auth/services.d.ts +21 -0
- package/dist/{src-DlPBctw_.js → auth-users-columns-BfQHf9JE.js} +1222 -86
- package/dist/auth-users-columns-BfQHf9JE.js.map +1 -0
- package/dist/{backup-service-CD8o_1Sl.js → backup-service-BH0Dzo_h.js} +2 -3
- package/dist/{backup-service-CD8o_1Sl.js.map → backup-service-BH0Dzo_h.js.map} +1 -1
- package/dist/cli-helpers.d.ts +57 -1
- package/dist/cli-output.d.ts +34 -0
- package/dist/data-transformer.d.ts +7 -2
- package/dist/data_driver-ULAyJEi9.js +193 -0
- package/dist/data_driver-ULAyJEi9.js.map +1 -0
- package/dist/ensure-collection-policies-8vuu-n4r.js +124 -0
- package/dist/ensure-collection-policies-8vuu-n4r.js.map +1 -0
- package/dist/{ensure-collection-tables-CBQdOETu.js → ensure-collection-tables-CbvaGuVn.js} +170 -20
- package/dist/ensure-collection-tables-CbvaGuVn.js.map +1 -0
- package/dist/index.es.js +1815 -1023
- package/dist/index.es.js.map +1 -1
- package/dist/rls-bootstrap-sql-69hYT8nr.js +244 -0
- package/dist/rls-bootstrap-sql-69hYT8nr.js.map +1 -0
- package/dist/rls-enforcement-BJ_3wxwg.js +425 -0
- package/dist/rls-enforcement-BJ_3wxwg.js.map +1 -0
- package/dist/schema/auth-schema.d.ts +102 -0
- package/dist/schema/auth-users-columns.d.ts +97 -0
- package/dist/schema/doctor-policy-checks.d.ts +28 -0
- package/dist/schema/doctor.d.ts +41 -25
- package/dist/schema/ensure-collection-policies.d.ts +33 -9
- package/dist/schema/ensure-collection-tables.d.ts +61 -7
- package/dist/schema/generate-drizzle-schema-logic.d.ts +10 -2
- package/dist/schema/generate-postgres-ddl-logic.d.ts +53 -5
- package/dist/schema/generated-schema-staleness.d.ts +39 -0
- package/dist/schema/introspect-db-inference.d.ts +8 -1
- package/dist/schema/introspect-db-logic.d.ts +49 -0
- package/dist/schema/introspect-db-project.d.ts +21 -0
- package/dist/schema/rls-bootstrap-sql.d.ts +135 -0
- package/dist/schema/search-column.d.ts +248 -0
- package/dist/security/policy-drift.d.ts +34 -0
- package/dist/security/rls-enforcement.d.ts +61 -5
- package/dist/services/FetchService.d.ts +34 -7
- package/dist/services/PersistService.d.ts +21 -17
- package/dist/services/RelationService.d.ts +9 -57
- package/dist/services/RelationWriteService.d.ts +82 -0
- package/dist/services/collection-helpers.d.ts +42 -0
- package/dist/services/dataService.d.ts +5 -0
- package/dist/services/junction-writes.d.ts +82 -0
- package/dist/services/realtimeService.d.ts +164 -23
- package/dist/services/write-denial.d.ts +36 -0
- package/dist/{src-DoU9yPqq.js → src-DCdn3Val.js} +124 -3
- package/dist/src-DCdn3Val.js.map +1 -0
- package/dist/utils/drizzle-conditions.d.ts +124 -2
- package/dist/{websocket-B2LsrINK.js → websocket-C8ZqVBiV.js} +75 -18
- package/dist/websocket-C8ZqVBiV.js.map +1 -0
- package/package.json +9 -8
- package/src/PostgresBackendDriver.ts +172 -6
- package/src/PostgresBootstrapper.ts +136 -11
- package/src/auth/ensure-tables.ts +212 -91
- package/src/auth/services.ts +82 -5
- package/src/backup/backup-cli.ts +59 -57
- package/src/cli-errors.ts +6 -6
- package/src/cli-helpers.ts +132 -13
- package/src/cli-output.ts +43 -0
- package/src/cli.ts +371 -161
- package/src/collections/buildRegistry.ts +3 -1
- package/src/collections/validate-relations.ts +124 -17
- package/src/data-transformer.ts +142 -28
- package/src/history/ensure-history-table.ts +9 -2
- package/src/schema/auth-schema.ts +17 -1
- package/src/schema/auth-users-columns.ts +131 -0
- package/src/schema/doctor-cli.ts +14 -65
- package/src/schema/doctor-policy-checks.ts +105 -0
- package/src/schema/doctor.ts +156 -77
- package/src/schema/ensure-collection-policies.ts +99 -6
- package/src/schema/ensure-collection-tables.ts +374 -32
- package/src/schema/generate-drizzle-schema-logic.ts +152 -66
- package/src/schema/generate-drizzle-schema.ts +11 -10
- package/src/schema/generate-postgres-ddl-logic.ts +294 -16
- package/src/schema/generate-postgres-ddl.ts +38 -14
- package/src/schema/generated-schema-staleness.ts +171 -0
- package/src/schema/introspect-db-inference.ts +9 -2
- package/src/schema/introspect-db-logic.ts +251 -75
- package/src/schema/introspect-db-project.ts +78 -0
- package/src/schema/introspect-db.ts +42 -25
- package/src/schema/introspect-runtime.ts +14 -2
- package/src/schema/non-sql-collections.test.ts +131 -0
- package/src/schema/rls-bootstrap-sql.ts +288 -0
- package/src/schema/search-column.ts +643 -0
- package/src/security/anonymous-grants.test.ts +4 -2
- package/src/security/policy-drift.test.ts +104 -3
- package/src/security/policy-drift.ts +129 -7
- package/src/security/rls-enforcement.ts +150 -7
- package/src/services/BranchService.ts +5 -0
- package/src/services/FetchService.ts +253 -115
- package/src/services/PersistService.ts +82 -43
- package/src/services/RelationService.ts +37 -696
- package/src/services/RelationWriteService.ts +653 -0
- package/src/services/cdc/trigger-cdc.ts +5 -1
- package/src/services/channel-history.ts +14 -0
- package/src/services/channel-presence.ts +13 -0
- package/src/services/collection-helpers.ts +89 -4
- package/src/services/dataService.ts +5 -0
- package/src/services/junction-writes.ts +295 -0
- package/src/services/pg-notify-listener.ts +1 -1
- package/src/services/realtimeService.ts +382 -118
- package/src/services/write-denial.ts +55 -0
- package/src/utils/drizzle-conditions.ts +433 -35
- package/src/utils/pg-error-utils.ts +8 -3
- package/src/websocket.ts +113 -16
- package/dist/ensure-collection-policies-ViG8XiPn.js +0 -57
- package/dist/ensure-collection-policies-ViG8XiPn.js.map +0 -1
- package/dist/ensure-collection-tables-CBQdOETu.js.map +0 -1
- package/dist/policy-CeA1JcxP.js +0 -105
- package/dist/policy-CeA1JcxP.js.map +0 -1
- package/dist/schema/auth-bootstrap-sql.d.ts +0 -24
- package/dist/src-DlPBctw_.js.map +0 -1
- package/dist/src-DoU9yPqq.js.map +0 -1
- package/dist/websocket-B2LsrINK.js.map +0 -1
- package/src/schema/auth-bootstrap-sql.ts +0 -47
|
@@ -3,7 +3,7 @@ import { BranchService } from "./services/BranchService";
|
|
|
3
3
|
import { RealtimeService } from "./services/realtimeService";
|
|
4
4
|
import { DatabasePoolManager } from "./databasePoolManager";
|
|
5
5
|
import { DrizzleClient } from "./interfaces";
|
|
6
|
-
import { DatabaseAdmin, DataDriver, DeleteProps, CollectionConfig, FetchCollectionProps, FetchOneProps, ListenCollectionProps, ListenOneProps, RebaseClient, RebaseSdkData, RestFetchService, SaveManyProps, SaveProps, TableMetadata, User } from "@rebasepro/types";
|
|
6
|
+
import { DatabaseAdmin, DataDriver, DeleteProps, CollectionConfig, FetchCollectionProps, FetchOneProps, ListenCollectionProps, ListenOneProps, RebaseClient, RebaseSdkData, RestFetchService, SaveManyProps, SaveProps, UpdateManyProps, DeleteManyProps, TableMetadata, User } from "@rebasepro/types";
|
|
7
7
|
import { PostgresCollectionRegistry } from "./collections/PostgresCollectionRegistry";
|
|
8
8
|
import { HistoryService } from "./history/HistoryService";
|
|
9
9
|
export declare class PostgresBackendDriver implements DataDriver {
|
|
@@ -62,6 +62,25 @@ export declare class PostgresBackendDriver implements DataDriver {
|
|
|
62
62
|
* REST/SDK read leaks unmasked data (see {@link applyAfterReadForRest}).
|
|
63
63
|
*/
|
|
64
64
|
get restFetchService(): RestFetchService;
|
|
65
|
+
/**
|
|
66
|
+
* Build the context handed to every collection callback.
|
|
67
|
+
*
|
|
68
|
+
* Note `data: this.data` — `this` is whichever driver is running the
|
|
69
|
+
* operation, so the callback's data plane inherits that driver's privilege.
|
|
70
|
+
* On a user request `AuthenticatedPostgresBackendDriver.withTransaction`
|
|
71
|
+
* constructs a fresh base driver bound to the RLS-scoped transaction and
|
|
72
|
+
* runs the operation on it, so `this.data` speaks through that connection
|
|
73
|
+
* and policies apply. On server-context work `this` is the base driver on
|
|
74
|
+
* the owner connection, and they do not. Pinned by the
|
|
75
|
+
* `"scopes context.data to the caller"` case in the `rls-enforcement` e2e
|
|
76
|
+
* suite, because it is the kind of property that is easy to break from a
|
|
77
|
+
* distance and impossible to notice.
|
|
78
|
+
*
|
|
79
|
+
* Previously returned through `as unknown as RebaseCallContext`, which
|
|
80
|
+
* disabled checking for the whole object and let `driver` — documented in
|
|
81
|
+
* the callbacks guide — sit on the runtime context while absent from the
|
|
82
|
+
* contract. Both are declared now, so this is a plain typed return.
|
|
83
|
+
*/
|
|
65
84
|
private buildCallContext;
|
|
66
85
|
private resolveCollectionCallbacks;
|
|
67
86
|
/**
|
|
@@ -102,6 +121,34 @@ export declare class PostgresBackendDriver implements DataDriver {
|
|
|
102
121
|
* with the last write winning, exactly as separate calls would.
|
|
103
122
|
*/
|
|
104
123
|
saveMany<M extends Record<string, unknown>>({ path, rows, collection, upsert }: SaveManyProps<M>): Promise<Record<string, unknown>[]>;
|
|
124
|
+
/**
|
|
125
|
+
* Update many rows through the same pipeline as {@link save}, in one
|
|
126
|
+
* transaction.
|
|
127
|
+
*
|
|
128
|
+
* Structurally the mirror of {@link saveMany} — same tx-bound sub-driver,
|
|
129
|
+
* same deferred notifications, same per-row error labelling — but it calls
|
|
130
|
+
* `save` with an explicit `id` and `status: "existing"`, which is precisely
|
|
131
|
+
* what `saveMany` cannot do: that one passes `status: "new"` and keeps the
|
|
132
|
+
* key inside `values`, so it inserts or upserts and can never target a
|
|
133
|
+
* particular row.
|
|
134
|
+
*
|
|
135
|
+
* All-or-nothing, so an id matching no row aborts the batch. A partial
|
|
136
|
+
* update is the outcome with no good recovery: the caller cannot tell which
|
|
137
|
+
* half landed without re-reading everything.
|
|
138
|
+
*/
|
|
139
|
+
updateMany<M extends Record<string, unknown>>({ path, updates, collection }: UpdateManyProps<M>): Promise<Record<string, unknown>[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Delete many rows in one transaction, running the full delete pipeline —
|
|
142
|
+
* `beforeDelete`, the delete, `afterDelete` — for each.
|
|
143
|
+
*
|
|
144
|
+
* Looping the single-row {@link delete} rather than emitting one
|
|
145
|
+
* `DELETE ... WHERE id = ANY($1)` is the deliberate choice: a single
|
|
146
|
+
* statement would be faster and would skip every callback, so a collection
|
|
147
|
+
* relying on `beforeDelete` to veto or on `afterDelete` to clean up
|
|
148
|
+
* dependents would behave differently depending on how many rows the caller
|
|
149
|
+
* happened to delete at once. Same pipeline, one transaction.
|
|
150
|
+
*/
|
|
151
|
+
deleteMany<M extends Record<string, unknown>>({ path, ids, collection }: DeleteManyProps<M>): Promise<void>;
|
|
105
152
|
delete<M extends Record<string, unknown>>({ row, collection }: DeleteProps<M>): Promise<void>;
|
|
106
153
|
deleteAll(path: string): Promise<void>;
|
|
107
154
|
checkUniqueField(path: string, name: string, value: unknown, id?: string, collection?: CollectionConfig): Promise<boolean>;
|
|
@@ -89,6 +89,32 @@ export interface PostgresDriverInternals {
|
|
|
89
89
|
* and this is the part that was wrong.
|
|
90
90
|
*/
|
|
91
91
|
export declare function resolveDriftCheckName(col: CollectionConfig, registeredTableNames: string[]): string;
|
|
92
|
+
/**
|
|
93
|
+
* Is this the local database `rebase init` scaffolds — i.e. the one case where
|
|
94
|
+
* "you are connected as a superuser" is not news?
|
|
95
|
+
*
|
|
96
|
+
* The scaffold's own `docker-compose.yml` sets `POSTGRES_USER: rebase_app`,
|
|
97
|
+
* which makes that role the cluster superuser, so the superuser advisory below
|
|
98
|
+
* was the only WARN a brand-new project ever saw and it was about a decision
|
|
99
|
+
* the tool had made for the developer.
|
|
100
|
+
*
|
|
101
|
+
* Of the two available fixes — provision a non-superuser table-owner role in
|
|
102
|
+
* the scaffold, or recognise the local shape and stay quiet — this is the
|
|
103
|
+
* second, because the first breaks the scaffold it is meant to improve: a
|
|
104
|
+
* non-superuser owner cannot `CREATE EXTENSION` (search collections need
|
|
105
|
+
* `pg_trgm`/`unaccent`, applied by `rebase db push` and again by the boot
|
|
106
|
+
* schema-ensure), so the very first `pnpm run db:push` on a scaffolded project
|
|
107
|
+
* with a search block would fail. Trading a working first run for a quieter log
|
|
108
|
+
* line is the wrong trade.
|
|
109
|
+
*
|
|
110
|
+
* The condition is deliberately narrow — a *non-production* process talking to
|
|
111
|
+
* a database on the loopback interface. A genuine production superuser
|
|
112
|
+
* connection still warns, and so does a non-production process pointed at a
|
|
113
|
+
* remote database (the usual "my dev machine writes to staging" mistake, where
|
|
114
|
+
* the advisory is exactly right). NODE_ENV alone would not do: the scaffold
|
|
115
|
+
* ships `NODE_ENV=development` and some deployments inherit it.
|
|
116
|
+
*/
|
|
117
|
+
export declare function isScaffoldedLocalDatabase(connectionString: string | undefined): boolean;
|
|
92
118
|
/**
|
|
93
119
|
* Default PostgreSQL bootstrapper.
|
|
94
120
|
*
|
package/dist/auth/services.d.ts
CHANGED
|
@@ -287,6 +287,7 @@ export declare class PostgresAuthRepository implements AuthRepository {
|
|
|
287
287
|
secretEncrypted: string;
|
|
288
288
|
}) | null>;
|
|
289
289
|
verifyMfaFactor(factorId: string): Promise<void>;
|
|
290
|
+
updateMfaFactorSecret(factorId: string, secretEncrypted: string): Promise<void>;
|
|
290
291
|
deleteMfaFactor(factorId: string, uid: string): Promise<void>;
|
|
291
292
|
createMfaChallenge(factorId: string, ipAddress?: string): Promise<MfaChallengeInfo>;
|
|
292
293
|
getMfaChallengeById(challengeId: string): Promise<MfaChallengeInfo | null>;
|
|
@@ -296,6 +297,8 @@ export declare class PostgresAuthRepository implements AuthRepository {
|
|
|
296
297
|
getUnusedRecoveryCodeCount(uid: string): Promise<number>;
|
|
297
298
|
deleteAllRecoveryCodes(uid: string): Promise<void>;
|
|
298
299
|
hasVerifiedMfaFactors(uid: string): Promise<boolean>;
|
|
300
|
+
claimMfaFactorCounter(factorId: string, counter: number): Promise<boolean>;
|
|
301
|
+
recordMfaChallengeAttempt(challengeId: string): Promise<number>;
|
|
299
302
|
}
|
|
300
303
|
/**
|
|
301
304
|
* PostgreSQL implementation of MfaRepository.
|
|
@@ -311,10 +314,28 @@ export declare class MfaService implements MfaRepository {
|
|
|
311
314
|
getMfaFactorById(factorId: string): Promise<(MfaFactor & {
|
|
312
315
|
secretEncrypted: string;
|
|
313
316
|
}) | null>;
|
|
317
|
+
/**
|
|
318
|
+
* Spend a TOTP time step, once and only once.
|
|
319
|
+
*
|
|
320
|
+
* One statement: the `WHERE` is the check, the `UPDATE` is the act, and
|
|
321
|
+
* `RETURNING` reports which of two concurrent requests carrying the same
|
|
322
|
+
* six digits won. Reading the counter and then writing it would let both
|
|
323
|
+
* pass — the exact replay this closes.
|
|
324
|
+
*/
|
|
325
|
+
claimMfaFactorCounter(factorId: string, counter: number): Promise<boolean>;
|
|
314
326
|
verifyMfaFactor(factorId: string): Promise<void>;
|
|
327
|
+
updateMfaFactorSecret(factorId: string, secretEncrypted: string): Promise<void>;
|
|
315
328
|
deleteMfaFactor(factorId: string, uid: string): Promise<void>;
|
|
316
329
|
createMfaChallenge(factorId: string, ipAddress?: string): Promise<MfaChallengeInfo>;
|
|
317
330
|
getMfaChallengeById(challengeId: string): Promise<MfaChallengeInfo | null>;
|
|
331
|
+
/**
|
|
332
|
+
* Count one failed guess against a challenge and report the new total.
|
|
333
|
+
*
|
|
334
|
+
* Incremented in the database rather than in the route so that guesses
|
|
335
|
+
* arriving in parallel — the shape any real brute-force takes — cannot
|
|
336
|
+
* share a single increment.
|
|
337
|
+
*/
|
|
338
|
+
recordMfaChallengeAttempt(challengeId: string): Promise<number>;
|
|
318
339
|
verifyMfaChallenge(challengeId: string): Promise<void>;
|
|
319
340
|
createRecoveryCodes(uid: string, codeHashes: string[]): Promise<void>;
|
|
320
341
|
useRecoveryCode(uid: string, codeHash: string): Promise<boolean>;
|